Skip to content

Commit 3e78777

Browse files
committed
Address feedback (p3)
1 parent d1ed25a commit 3e78777

32 files changed

+1454
-1453
lines changed

docs/02_concepts/code/05_retries_sync.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
TOKEN = 'MY-APIFY-TOKEN'
66

77

8-
async def main() -> None:
8+
def main() -> None:
99
apify_client = ApifyClient(
1010
token=TOKEN,
1111
max_retries=8,

docs/03_examples/code/02_tasks_async.py

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
11
import asyncio
22

33
from apify_client import ApifyClientAsync
4-
from apify_client._models import Run, Task
5-
from apify_client._resource_clients import TaskClientAsync
64

75
TOKEN = 'MY-APIFY-TOKEN'
86
HASHTAGS = ['zebra', 'lion', 'hippo']
97

108

11-
async def run_apify_task(client: TaskClientAsync) -> Run | None:
12-
return await client.call()
13-
14-
159
async def main() -> None:
1610
apify_client = ApifyClientAsync(token=TOKEN)
1711

1812
# Create Apify tasks
19-
apify_tasks = list[Task]()
13+
apify_tasks = []
2014
apify_tasks_client = apify_client.tasks()
2115

2216
for hashtag in HASHTAGS:
@@ -31,20 +25,19 @@ async def main() -> None:
3125
print('Tasks created:', apify_tasks)
3226

3327
# Create Apify task clients
34-
apify_task_clients = list[TaskClientAsync]()
35-
36-
for apify_task in apify_tasks:
37-
task_id = apify_task.id
38-
apify_task_client = apify_client.task(task_id)
39-
apify_task_clients.append(apify_task_client)
28+
apify_task_clients = [apify_client.task(task.id) for task in apify_tasks]
4029

4130
print('Task clients created:', apify_task_clients)
4231

4332
# Execute Apify tasks
44-
run_apify_tasks = [run_apify_task(client) for client in apify_task_clients]
45-
task_run_results = await asyncio.gather(*run_apify_tasks)
33+
task_run_results = await asyncio.gather(
34+
*[client.call() for client in apify_task_clients]
35+
)
36+
37+
# Filter out None results (tasks that failed to return a run)
38+
successful_runs = [run for run in task_run_results if run is not None]
4639

47-
print('Task results:', task_run_results)
40+
print('Task results:', successful_runs)
4841

4942

5043
if __name__ == '__main__':

docs/03_examples/code/02_tasks_sync.py

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
from apify_client import ApifyClient
2-
from apify_client._models import Run, Task
3-
from apify_client._resource_clients import TaskClient
42

53
TOKEN = 'MY-APIFY-TOKEN'
64
HASHTAGS = ['zebra', 'lion', 'hippo']
75

86

9-
def run_apify_task(client: TaskClient) -> Run | None:
10-
return client.call()
11-
12-
137
def main() -> None:
148
apify_client = ApifyClient(token=TOKEN)
159

1610
# Create Apify tasks
17-
apify_tasks = list[Task]()
11+
apify_tasks = []
1812
apify_tasks_client = apify_client.tasks()
1913

2014
for hashtag in HASHTAGS:
@@ -29,24 +23,17 @@ def main() -> None:
2923
print('Tasks created:', apify_tasks)
3024

3125
# Create Apify task clients
32-
apify_task_clients = list[TaskClient]()
33-
34-
for apify_task in apify_tasks:
35-
task_id = apify_task.id
36-
apify_task_client = apify_client.task(task_id)
37-
apify_task_clients.append(apify_task_client)
26+
apify_task_clients = [apify_client.task(task.id) for task in apify_tasks]
3827

3928
print('Task clients created:', apify_task_clients)
4029

4130
# Execute Apify tasks
42-
task_run_results = list[Run]()
31+
task_run_results = [client.call() for client in apify_task_clients]
4332

44-
for client in apify_task_clients:
45-
result = run_apify_task(client)
46-
if result is not None:
47-
task_run_results.append(result)
33+
# Filter out None results (tasks that failed to return a run)
34+
successful_runs = [run for run in task_run_results if run is not None]
4835

49-
print('Task results:', task_run_results)
36+
print('Task results:', successful_runs)
5037

5138

5239
if __name__ == '__main__':

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,10 @@ install-sync = "uv sync --all-extras"
217217
build = "uv build"
218218
publish-to-pypi = "uv publish --token ${APIFY_PYPI_TOKEN_CRAWLEE}"
219219
type-check = "uv run ty check"
220-
unit-tests = "uv run pytest --numprocesses=${TESTS_CONCURRENCY:-16} tests/unit"
221-
unit-tests-cov = "uv run pytest --numprocesses=${TESTS_CONCURRENCY:-16} --cov=src/apify_client --cov-report=xml:coverage-unit.xml tests/unit"
222-
integration-tests = "uv run pytest --numprocesses=${TESTS_CONCURRENCY:-16} tests/integration"
223-
integration-tests-cov = "uv run pytest --numprocesses=${TESTS_CONCURRENCY:-16} --cov=src/apify_client --cov-report=xml:coverage-integration.xml tests/integration"
220+
unit-tests = "uv run pytest --numprocesses=${TESTS_CONCURRENCY:-auto} tests/unit"
221+
unit-tests-cov = "uv run pytest --numprocesses=${TESTS_CONCURRENCY:-auto} --cov=src/apify_client --cov-report=xml:coverage-unit.xml tests/unit"
222+
integration-tests = "uv run pytest --numprocesses=${TESTS_CONCURRENCY:-auto} tests/integration"
223+
integration-tests-cov = "uv run pytest --numprocesses=${TESTS_CONCURRENCY:-auto} --cov=src/apify_client --cov-report=xml:coverage-integration.xml tests/integration"
224224
check-async-docstrings = "uv run python scripts/check_async_docstrings.py"
225225
fix-async-docstrings = "uv run python scripts/fix_async_docstrings.py"
226226
check-code = ["lint", "type-check", "unit-tests", "check-async-docstrings"]

src/apify_client/_apify_client.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ def __init__(
129129
"""Collector for client request statistics."""
130130

131131
self._http_client = HttpClient(
132-
token=token,
133-
timeout=timeout or DEFAULT_TIMEOUT,
134-
max_retries=max_retries or DEFAULT_MAX_RETRIES,
135-
min_delay_between_retries=min_delay_between_retries or DEFAULT_MIN_DELAY_BETWEEN_RETRIES,
132+
token=self._token,
133+
timeout=timeout,
134+
max_retries=max_retries,
135+
min_delay_between_retries=min_delay_between_retries,
136136
statistics=self._statistics,
137137
headers=headers,
138138
)
@@ -390,10 +390,10 @@ def __init__(
390390
"""Collector for client request statistics."""
391391

392392
self._http_client = HttpClientAsync(
393-
token=token,
394-
timeout=timeout or DEFAULT_TIMEOUT,
395-
max_retries=max_retries or DEFAULT_MAX_RETRIES,
396-
min_delay_between_retries=min_delay_between_retries or DEFAULT_MIN_DELAY_BETWEEN_RETRIES,
393+
token=self._token,
394+
timeout=timeout,
395+
max_retries=max_retries,
396+
min_delay_between_retries=min_delay_between_retries,
397397
statistics=self._statistics,
398398
headers=headers,
399399
)

src/apify_client/_logging.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ def format(self, record: logging.LogRecord) -> str:
6767
Formatted log message with colored logger name prefix.
6868
"""
6969
formatted_logger_name = f'{Fore.CYAN}[{record.name}]{Style.RESET_ALL}'
70-
message = record.getMessage()
71-
return f'{formatted_logger_name} -> {message}'
70+
formatted_message = super().format(record)
71+
return f'{formatted_logger_name} -> {formatted_message}'
7272

7373

7474
def create_redirect_logger(name: str) -> logging.Logger:

src/apify_client/_representations.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ def get_actor_repr(
174174

175175

176176
def get_task_repr(
177+
*,
177178
actor_id: str | None = None,
178179
name: str | None = None,
179180
task_input: dict | None = None,
@@ -187,7 +188,6 @@ def get_task_repr(
187188
actor_standby_idle_timeout: timedelta | None = None,
188189
actor_standby_build: str | None = None,
189190
actor_standby_memory_mbytes: int | None = None,
190-
*,
191191
restart_on_error: bool | None = None,
192192
) -> dict:
193193
"""Get the dictionary representation of a task."""
@@ -240,13 +240,13 @@ def get_actor_version_repr(
240240

241241

242242
def get_schedule_repr(
243+
*,
243244
cron_expression: str | None = None,
244245
name: str | None = None,
245246
actions: list[dict] | None = None,
246247
description: str | None = None,
247248
timezone: str | None = None,
248249
title: str | None = None,
249-
*,
250250
is_enabled: bool | None = None,
251251
is_exclusive: bool | None = None,
252252
) -> dict:
@@ -293,7 +293,7 @@ def get_webhook_repr(
293293
),
294294
}
295295

296-
if actor_run_id is not None:
296+
if actor_run_id is not None and is_ad_hoc is None:
297297
webhook['isAdHoc'] = True
298298

299299
if event_types is not None:

src/apify_client/_resource_clients/__init__.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,16 @@
1010
from .dataset_collection import DatasetCollectionClient, DatasetCollectionClientAsync
1111
from .key_value_store import KeyValueStoreClient, KeyValueStoreClientAsync
1212
from .key_value_store_collection import KeyValueStoreCollectionClient, KeyValueStoreCollectionClientAsync
13-
from .log import (
14-
LogClient,
15-
LogClientAsync,
16-
StatusMessageWatcher,
17-
StatusMessageWatcherAsync,
18-
StatusMessageWatcherSync,
19-
StreamedLog,
20-
StreamedLogAsync,
21-
StreamedLogSync,
22-
)
13+
from .log import LogClient, LogClientAsync
2314
from .request_queue import RequestQueueClient, RequestQueueClientAsync
2415
from .request_queue_collection import RequestQueueCollectionClient, RequestQueueCollectionClientAsync
2516
from .run import RunClient, RunClientAsync
2617
from .run_collection import RunCollectionClient, RunCollectionClientAsync
2718
from .schedule import ScheduleClient, ScheduleClientAsync
2819
from .schedule_collection import ScheduleCollectionClient, ScheduleCollectionClientAsync
20+
from .status_message_watcher import StatusMessageWatcher, StatusMessageWatcherAsync, StatusMessageWatcherSync
2921
from .store_collection import StoreCollectionClient, StoreCollectionClientAsync
22+
from .streamed_log import StreamedLog, StreamedLogAsync, StreamedLogSync
3023
from .task import TaskClient, TaskClientAsync
3124
from .task_collection import TaskCollectionClient, TaskCollectionClientAsync
3225
from .user import UserClient, UserClientAsync

src/apify_client/_resource_clients/_resource_client.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def _build_url(
9898
Returns:
9999
Complete URL with optional path and query string.
100100
"""
101-
url = f'{self._resource_url}/{path}' if path else self._resource_url
101+
url = f'{self._resource_url}/{path}' if path is not None else self._resource_url
102102

103103
if public:
104104
if not url.startswith(self._base_url):
@@ -254,16 +254,16 @@ def _wait_for_finish(
254254
remaining_secs = max(0, int(to_seconds(deadline - datetime.now(timezone.utc))))
255255
wait_for_finish = remaining_secs
256256
else:
257-
wait_for_finish = to_seconds(DEFAULT_WAIT_FOR_FINISH)
257+
wait_for_finish = to_seconds(DEFAULT_WAIT_FOR_FINISH, as_int=True)
258258

259259
try:
260260
response = self._http_client.call(
261261
url=url,
262262
method='GET',
263263
params={**params, 'waitForFinish': wait_for_finish},
264264
)
265-
response_as_dict = response_to_dict(response)
266-
actor_job_response = ActorJobResponse.model_validate(response_as_dict)
265+
result = response_to_dict(response)
266+
actor_job_response = ActorJobResponse.model_validate(result)
267267
actor_job = actor_job_response.data.model_dump()
268268

269269
is_terminal = actor_job_response.data.status in TERMINAL_STATUSES
@@ -420,16 +420,16 @@ async def _wait_for_finish(
420420
remaining_secs = max(0, int(to_seconds(deadline - datetime.now(timezone.utc))))
421421
wait_for_finish = remaining_secs
422422
else:
423-
wait_for_finish = to_seconds(DEFAULT_WAIT_FOR_FINISH)
423+
wait_for_finish = to_seconds(DEFAULT_WAIT_FOR_FINISH, as_int=True)
424424

425425
try:
426426
response = await self._http_client.call(
427427
url=url,
428428
method='GET',
429429
params={**params, 'waitForFinish': wait_for_finish},
430430
)
431-
response_as_dict = response_to_dict(response)
432-
actor_job_response = ActorJobResponse.model_validate(response_as_dict)
431+
result = response_to_dict(response)
432+
actor_job_response = ActorJobResponse.model_validate(result)
433433
actor_job = actor_job_response.data.model_dump()
434434

435435
is_terminal = actor_job_response.data.status in TERMINAL_STATUSES

src/apify_client/_resource_clients/actor.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,8 @@ def start(
258258
params=request_params,
259259
)
260260

261-
response_as_dict = response_to_dict(response)
262-
return RunResponse.model_validate(response_as_dict).data
261+
result = response_to_dict(response)
262+
return RunResponse.model_validate(result).data
263263

264264
def call(
265265
self,
@@ -383,7 +383,8 @@ def build(
383383
params=request_params,
384384
)
385385

386-
return BuildResponse.model_validate(response_to_dict(response)).data
386+
result = response_to_dict(response)
387+
return BuildResponse.model_validate(result).data
387388

388389
def builds(self) -> BuildCollectionClient:
389390
"""Retrieve a client for the builds of this Actor."""
@@ -420,10 +421,10 @@ def default_build(
420421
)
421422

422423
response = self._http_client.call(url=self._build_url('builds/default'), method='GET', params=request_params)
423-
response_as_dict = response_to_dict(response)
424+
result = response_to_dict(response)
424425

425426
return self._client_registry.build_client(
426-
resource_id=response_as_dict['data']['id'],
427+
resource_id=result['data']['id'],
427428
base_url=self._base_url,
428429
public_base_url=self._public_base_url,
429430
http_client=self._http_client,
@@ -716,8 +717,8 @@ async def start(
716717
params=request_params,
717718
)
718719

719-
response_as_dict = response_to_dict(response)
720-
return RunResponse.model_validate(response_as_dict).data
720+
result = response_to_dict(response)
721+
return RunResponse.model_validate(result).data
721722

722723
async def call(
723724
self,
@@ -845,8 +846,8 @@ async def build(
845846
params=request_params,
846847
)
847848

848-
response_as_dict = response_to_dict(response)
849-
return BuildResponse.model_validate(response_as_dict).data
849+
result = response_to_dict(response)
850+
return BuildResponse.model_validate(result).data
850851

851852
def builds(self) -> BuildCollectionClientAsync:
852853
"""Retrieve a client for the builds of this Actor."""
@@ -887,10 +888,10 @@ async def default_build(
887888
method='GET',
888889
params=request_params,
889890
)
890-
response_as_dict = response_to_dict(response)
891+
result = response_to_dict(response)
891892

892893
return self._client_registry.build_client(
893-
resource_id=response_as_dict['data']['id'],
894+
resource_id=result['data']['id'],
894895
base_url=self._base_url,
895896
public_base_url=self._public_base_url,
896897
http_client=self._http_client,

0 commit comments

Comments
 (0)