apify-client 3.0.2b3__tar.gz → 3.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. {apify_client-3.0.2b3 → apify_client-3.0.3}/CHANGELOG.md +9 -3
  2. {apify_client-3.0.2b3 → apify_client-3.0.3}/PKG-INFO +4 -3
  3. {apify_client-3.0.2b3 → apify_client-3.0.3}/README.md +2 -1
  4. {apify_client-3.0.2b3 → apify_client-3.0.3}/pyproject.toml +2 -2
  5. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_models.py +16 -0
  6. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/actor.py +2 -2
  7. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/actor_collection.py +2 -2
  8. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_streamed_log.py +13 -9
  9. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_typeddicts.py +32 -0
  10. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_utils.py +10 -16
  11. {apify_client-3.0.2b3 → apify_client-3.0.3}/.gitignore +0 -0
  12. {apify_client-3.0.2b3 → apify_client-3.0.3}/CONTRIBUTING.md +0 -0
  13. {apify_client-3.0.2b3 → apify_client-3.0.3}/LICENSE +0 -0
  14. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/__init__.py +0 -0
  15. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_apify_client.py +0 -0
  16. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_client_registry.py +0 -0
  17. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_consts.py +0 -0
  18. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_docs.py +0 -0
  19. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_literals.py +0 -0
  20. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_logging.py +0 -0
  21. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_pagination.py +0 -0
  22. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/__init__.py +0 -0
  23. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/_resource_client.py +0 -0
  24. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/actor_env_var.py +0 -0
  25. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/actor_env_var_collection.py +0 -0
  26. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/actor_version.py +0 -0
  27. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/actor_version_collection.py +0 -0
  28. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/build.py +0 -0
  29. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/build_collection.py +0 -0
  30. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/dataset.py +0 -0
  31. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/dataset_collection.py +0 -0
  32. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/key_value_store.py +0 -0
  33. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/key_value_store_collection.py +0 -0
  34. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/log.py +0 -0
  35. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/request_queue.py +0 -0
  36. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/request_queue_collection.py +0 -0
  37. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/run.py +0 -0
  38. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/run_collection.py +0 -0
  39. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/schedule.py +0 -0
  40. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/schedule_collection.py +0 -0
  41. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/store_collection.py +0 -0
  42. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/task.py +0 -0
  43. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/task_collection.py +0 -0
  44. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/user.py +0 -0
  45. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/webhook.py +0 -0
  46. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/webhook_collection.py +0 -0
  47. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/webhook_dispatch.py +0 -0
  48. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_resource_clients/webhook_dispatch_collection.py +0 -0
  49. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_statistics.py +0 -0
  50. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/_status_message_watcher.py +0 -0
  51. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/errors.py +0 -0
  52. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/http_clients/__init__.py +0 -0
  53. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/http_clients/_base.py +0 -0
  54. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/http_clients/_impit.py +0 -0
  55. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/py.typed +0 -0
  56. {apify_client-3.0.2b3 → apify_client-3.0.3}/src/apify_client/types.py +0 -0
@@ -2,8 +2,15 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- <!-- git-cliff-unreleased-start -->
6
- ## 3.0.2 - **not yet released**
5
+ ## [3.0.3](https://github.com/apify/apify-client-python/releases/tag/v3.0.3) (2026-06-18)
6
+
7
+ ### 🐛 Bug Fixes
8
+
9
+ - Include all supported fields for ad-hoc webhooks ([#855](https://github.com/apify/apify-client-python/pull/855)) ([6eb267d](https://github.com/apify/apify-client-python/commit/6eb267dbe620cb9d864c2390a84dfeb851cecc7c)) by [@apify-service-account](https://github.com/apify-service-account)
10
+ - Only log any error that happens during log redirection ([#866](https://github.com/apify/apify-client-python/pull/866)) ([a2cc987](https://github.com/apify/apify-client-python/commit/a2cc987b6d1ef1d06b37a179876b12ee4f739f5f)) by [@Pijukatel](https://github.com/Pijukatel), closes [#864](https://github.com/apify/apify-client-python/issues/864)
11
+
12
+
13
+ ## [3.0.2](https://github.com/apify/apify-client-python/releases/tag/v3.0.2) (2026-05-26)
7
14
 
8
15
  ### 🐛 Bug Fixes
9
16
 
@@ -12,7 +19,6 @@ All notable changes to this project will be documented in this file.
12
19
  - Flush StreamedLogAsync tail when stop() cancels the task ([#754](https://github.com/apify/apify-client-python/pull/754)) ([ea23338](https://github.com/apify/apify-client-python/commit/ea2333822937c4ad9b72fbba63e6fd7b52343055)) by [@vdusek](https://github.com/vdusek)
13
20
 
14
21
 
15
- <!-- git-cliff-unreleased-end -->
16
22
  ## [3.0.1](https://github.com/apify/apify-client-python/releases/tag/v3.0.1) (2026-05-22)
17
23
 
18
24
  ### 🐛 Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apify_client
3
- Version: 3.0.2b3
3
+ Version: 3.0.3
4
4
  Summary: Apify API client for Python
5
5
  Project-URL: Apify Homepage, https://apify.com
6
6
  Project-URL: Homepage, https://docs.apify.com/api/client/python/
@@ -225,7 +225,7 @@ Classifier: Programming Language :: Python :: 3.14
225
225
  Classifier: Topic :: Software Development :: Libraries
226
226
  Requires-Python: >=3.11
227
227
  Requires-Dist: colorama>=0.4.0
228
- Requires-Dist: impit>=0.9.2
228
+ Requires-Dist: impit~=0.12.0
229
229
  Requires-Dist: more-itertools>=10.0.0
230
230
  Requires-Dist: pydantic[email]>=2.11.0
231
231
  Description-Content-Type: text/markdown
@@ -239,7 +239,8 @@ Description-Content-Type: text/markdown
239
239
  <p align="center">
240
240
  <a href="https://pypi.org/project/apify-client/"><img src="https://badge.fury.io/py/apify-client.svg" alt="PyPI version"></a>
241
241
  <a href="https://pypi.org/project/apify-client/"><img src="https://img.shields.io/pypi/dm/apify-client" alt="PyPI downloads"></a>
242
- <a href="https://pypi.org/project/apify-client/"><img src="https://img.shields.io/pypi/pyversions/apify-client" alt="Python versions"></a>
242
+ <a href="https://pypi.org/project/apify-client/"><img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python versions"></a>
243
+ <a href="https://github.com/apify/apify-client-python/actions/workflows/on_master.yaml"><img src="https://github.com/apify/apify-client-python/actions/workflows/on_master.yaml/badge.svg?branch=master" alt="Build status"></a>
243
244
  <a href="https://codecov.io/gh/apify/apify-client-python"><img src="https://codecov.io/gh/apify/apify-client-python/graph/badge.svg?token=TYQQWYYZ7A" alt="Coverage"></a>
244
245
  <a href="https://github.com/apify/apify-client-python/blob/master/LICENSE"><img src="https://img.shields.io/pypi/l/apify-client" alt="License"></a>
245
246
  <a href="https://discord.gg/jyEM2PRvMU"><img src="https://img.shields.io/discord/801163717915574323?label=discord" alt="Chat on Discord"></a>
@@ -7,7 +7,8 @@
7
7
  <p align="center">
8
8
  <a href="https://pypi.org/project/apify-client/"><img src="https://badge.fury.io/py/apify-client.svg" alt="PyPI version"></a>
9
9
  <a href="https://pypi.org/project/apify-client/"><img src="https://img.shields.io/pypi/dm/apify-client" alt="PyPI downloads"></a>
10
- <a href="https://pypi.org/project/apify-client/"><img src="https://img.shields.io/pypi/pyversions/apify-client" alt="Python versions"></a>
10
+ <a href="https://pypi.org/project/apify-client/"><img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python versions"></a>
11
+ <a href="https://github.com/apify/apify-client-python/actions/workflows/on_master.yaml"><img src="https://github.com/apify/apify-client-python/actions/workflows/on_master.yaml/badge.svg?branch=master" alt="Build status"></a>
11
12
  <a href="https://codecov.io/gh/apify/apify-client-python"><img src="https://codecov.io/gh/apify/apify-client-python/graph/badge.svg?token=TYQQWYYZ7A" alt="Coverage"></a>
12
13
  <a href="https://github.com/apify/apify-client-python/blob/master/LICENSE"><img src="https://img.shields.io/pypi/l/apify-client" alt="License"></a>
13
14
  <a href="https://discord.gg/jyEM2PRvMU"><img src="https://img.shields.io/discord/801163717915574323?label=discord" alt="Chat on Discord"></a>
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "apify_client"
7
- version = "3.0.2b3"
7
+ version = "3.0.3"
8
8
  description = "Apify API client for Python"
9
9
  authors = [{ name = "Apify Technologies s.r.o.", email = "support@apify.com" }]
10
10
  license = { file = "LICENSE" }
@@ -25,7 +25,7 @@ classifiers = [
25
25
  keywords = ["apify", "api", "client", "automation", "crawling", "scraping"]
26
26
  dependencies = [
27
27
  "colorama>=0.4.0",
28
- "impit>=0.9.2",
28
+ "impit~=0.12.0",
29
29
  "more_itertools>=10.0.0",
30
30
  "pydantic[email]>=2.11.0",
31
31
  ]
@@ -3766,6 +3766,22 @@ class WebhookRepresentation(BaseModel):
3766
3766
  """
3767
3767
  Optional template for the HTTP headers sent by the webhook.
3768
3768
  """
3769
+ should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None
3770
+ """
3771
+ Flag to also interpolate `{{...}}` variables inside string values of the payload and headers templates.
3772
+ """
3773
+ idempotency_key: Annotated[str | None, Field(alias='idempotencyKey', examples=['fdSJmdP3nfs7sfk3y'])] = None
3774
+ """
3775
+ Key that prevents creating duplicate webhooks, e.g. when the run-starting request is retried.
3776
+ """
3777
+ ignore_ssl_errors: Annotated[bool | None, Field(alias='ignoreSslErrors', examples=[False])] = None
3778
+ """
3779
+ Flag to ignore SSL errors when the webhook sends the request.
3780
+ """
3781
+ do_not_retry: Annotated[bool | None, Field(alias='doNotRetry', examples=[False])] = None
3782
+ """
3783
+ Flag to skip retrying the webhook request on failure.
3784
+ """
3769
3785
 
3770
3786
 
3771
3787
  @docs_group('Models')
@@ -75,7 +75,7 @@ class ActorClient(ResourceClient):
75
75
  self,
76
76
  *,
77
77
  resource_id: str,
78
- resource_path: str = 'acts',
78
+ resource_path: str = 'actors',
79
79
  **kwargs: Any,
80
80
  ) -> None:
81
81
  super().__init__(
@@ -571,7 +571,7 @@ class ActorClientAsync(ResourceClientAsync):
571
571
  self,
572
572
  *,
573
573
  resource_id: str,
574
- resource_path: str = 'acts',
574
+ resource_path: str = 'actors',
575
575
  **kwargs: Any,
576
576
  ) -> None:
577
577
  super().__init__(
@@ -36,7 +36,7 @@ class ActorCollectionClient(ResourceClient):
36
36
  def __init__(
37
37
  self,
38
38
  *,
39
- resource_path: str = 'acts',
39
+ resource_path: str = 'actors',
40
40
  **kwargs: Any,
41
41
  ) -> None:
42
42
  super().__init__(
@@ -215,7 +215,7 @@ class ActorCollectionClientAsync(ResourceClientAsync):
215
215
  def __init__(
216
216
  self,
217
217
  *,
218
- resource_path: str = 'acts',
218
+ resource_path: str = 'actors',
219
219
  **kwargs: Any,
220
220
  ) -> None:
221
221
  super().__init__(
@@ -215,12 +215,16 @@ class StreamedLogAsync(StreamedLogBase):
215
215
  await self.stop()
216
216
 
217
217
  async def _stream_log(self) -> None:
218
- async with self._log_client.stream(raw=True) as log_stream:
219
- if not log_stream:
220
- return
221
- try:
222
- async for data in log_stream.aiter_bytes():
223
- self._process_new_data(data)
224
- finally:
225
- # Flush the last buffered part even if the task is cancelled by `stop()`.
226
- self._log_buffer_content(include_last_part=True)
218
+ try:
219
+ async with self._log_client.stream(raw=True) as log_stream:
220
+ if not log_stream:
221
+ return
222
+ try:
223
+ async for data in log_stream.aiter_bytes():
224
+ self._process_new_data(data)
225
+ finally:
226
+ # Flush the last buffered part even if the task is cancelled by `stop()`.
227
+ self._log_buffer_content(include_last_part=True)
228
+ except Exception:
229
+ # Exception in log redirection should not propagate further.
230
+ self._to_logger.exception('Log redirection stopped due to unexpected error:')
@@ -336,6 +336,22 @@ class WebhookRepresentationDict(TypedDict):
336
336
  """
337
337
  Optional template for the HTTP headers sent by the webhook.
338
338
  """
339
+ should_interpolate_strings: NotRequired[bool | None]
340
+ """
341
+ Flag to also interpolate `{{...}}` variables inside string values of the payload and headers templates.
342
+ """
343
+ idempotency_key: NotRequired[str | None]
344
+ """
345
+ Key that prevents creating duplicate webhooks, e.g. when the run-starting request is retried.
346
+ """
347
+ ignore_ssl_errors: NotRequired[bool | None]
348
+ """
349
+ Flag to ignore SSL errors when the webhook sends the request.
350
+ """
351
+ do_not_retry: NotRequired[bool | None]
352
+ """
353
+ Flag to skip retrying the webhook request on failure.
354
+ """
339
355
 
340
356
 
341
357
  @docs_group('Typed dicts')
@@ -374,3 +390,19 @@ class WebhookRepresentationCamelDict(TypedDict):
374
390
  """
375
391
  Optional template for the HTTP headers sent by the webhook.
376
392
  """
393
+ shouldInterpolateStrings: NotRequired[bool | None]
394
+ """
395
+ Flag to also interpolate `{{...}}` variables inside string values of the payload and headers templates.
396
+ """
397
+ idempotencyKey: NotRequired[str | None]
398
+ """
399
+ Key that prevents creating duplicate webhooks, e.g. when the run-starting request is retried.
400
+ """
401
+ ignoreSslErrors: NotRequired[bool | None]
402
+ """
403
+ Flag to ignore SSL errors when the webhook sends the request.
404
+ """
405
+ doNotRetry: NotRequired[bool | None]
406
+ """
407
+ Flag to skip retrying the webhook request on failure.
408
+ """
@@ -288,31 +288,25 @@ def encode_webhooks_to_base64(webhooks: WebhooksList | None) -> str | None:
288
288
 
289
289
  Returns `None` for `None` or an empty list, so the query parameter is omitted.
290
290
 
291
- See `WebhooksList` for the accepted shapes. `WebhookRepresentation` instances are used as-is; `WebhookCreate`
292
- instances are projected onto the `WebhookRepresentation` fields, dropping persistent-only fields like `condition`.
293
- Dict shapes are validated into `WebhookRepresentation` and only fields it declares are kept.
291
+ See `WebhooksList` for the accepted shapes. `WebhookRepresentation` instances are used as-is. `WebhookCreate`
292
+ instances and dict shapes are projected onto the fields `WebhookRepresentation` declares, dropping anything else
293
+ (e.g. persistent-only fields like `condition`). Filtering by the declared field names and aliases means new
294
+ ad-hoc fields added to `WebhookRepresentation` flow through automatically, without touching this function.
294
295
  """
295
296
  if not webhooks:
296
297
  return None
297
298
 
298
299
  representations = list[WebhookRepresentation]()
300
+ allowed = _webhook_representation_keys()
299
301
 
300
302
  for webhook in webhooks:
301
303
  if isinstance(webhook, WebhookRepresentation):
302
304
  representations.append(webhook)
303
- elif isinstance(webhook, WebhookCreate):
304
- representations.append(
305
- WebhookRepresentation(
306
- event_types=webhook.event_types,
307
- request_url=webhook.request_url,
308
- payload_template=webhook.payload_template,
309
- headers_template=webhook.headers_template,
310
- )
311
- )
312
- else:
313
- allowed = _webhook_representation_keys()
314
- filtered = {k: v for k, v in webhook.items() if k in allowed}
315
- representations.append(WebhookRepresentation.model_validate(filtered))
305
+ continue
306
+
307
+ data = webhook.model_dump(by_alias=True) if isinstance(webhook, WebhookCreate) else dict(webhook)
308
+ filtered = {key: value for key, value in data.items() if key in allowed}
309
+ representations.append(WebhookRepresentation.model_validate(filtered))
316
310
 
317
311
  data = [r.model_dump(by_alias=True, exclude_none=True) for r in representations]
318
312
  json_string = json.dumps(data).encode(encoding='utf-8')
File without changes
File without changes