apify-client 3.2.0__tar.gz → 3.2.1b1__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 (68) hide show
  1. {apify_client-3.2.0 → apify_client-3.2.1b1}/CHANGELOG.md +5 -0
  2. {apify_client-3.2.0 → apify_client-3.2.1b1}/PKG-INFO +3 -3
  3. {apify_client-3.2.0 → apify_client-3.2.1b1}/README.md +2 -2
  4. {apify_client-3.2.0 → apify_client-3.2.1b1}/pyproject.toml +1 -1
  5. {apify_client-3.2.0 → apify_client-3.2.1b1}/pyproject.toml.orig +1 -1
  6. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_streamed_log.py +3 -3
  7. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_clients/__init__.py +1 -1
  8. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_clients/_httpx2.py +47 -47
  9. {apify_client-3.2.0 → apify_client-3.2.1b1}/CONTRIBUTING.md +0 -0
  10. {apify_client-3.2.0 → apify_client-3.2.1b1}/LICENSE +0 -0
  11. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/__init__.py +0 -0
  12. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_apify_client.py +0 -0
  13. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_client_registry.py +0 -0
  14. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_consts.py +0 -0
  15. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_docs.py +0 -0
  16. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_literals.py +0 -0
  17. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_logging.py +0 -0
  18. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_models.py +0 -0
  19. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_pagination.py +0 -0
  20. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/__init__.py +0 -0
  21. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/_resource_client.py +0 -0
  22. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/actor.py +0 -0
  23. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/actor_collection.py +0 -0
  24. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/actor_env_var.py +0 -0
  25. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/actor_env_var_collection.py +0 -0
  26. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/actor_version.py +0 -0
  27. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/actor_version_collection.py +0 -0
  28. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/build.py +0 -0
  29. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/build_collection.py +0 -0
  30. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/dataset.py +0 -0
  31. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/dataset_collection.py +0 -0
  32. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/key_value_store.py +0 -0
  33. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/key_value_store_collection.py +0 -0
  34. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/log.py +0 -0
  35. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/request_queue.py +0 -0
  36. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/request_queue_collection.py +0 -0
  37. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/run.py +0 -0
  38. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/run_collection.py +0 -0
  39. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/schedule.py +0 -0
  40. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/schedule_collection.py +0 -0
  41. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/store_collection.py +0 -0
  42. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/task.py +0 -0
  43. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/task_collection.py +0 -0
  44. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/user.py +0 -0
  45. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/webhook.py +0 -0
  46. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/webhook_collection.py +0 -0
  47. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/webhook_dispatch.py +0 -0
  48. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_resource_clients/webhook_dispatch_collection.py +0 -0
  49. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_statistics.py +0 -0
  50. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_status_message_watcher.py +0 -0
  51. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_typeddicts.py +0 -0
  52. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_utils/__init__.py +0 -0
  53. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_utils/crypto.py +0 -0
  54. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_utils/encoding.py +0 -0
  55. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_utils/errors.py +0 -0
  56. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_utils/http.py +0 -0
  57. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_utils/time.py +0 -0
  58. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/_utils/try_import.py +0 -0
  59. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/errors.py +0 -0
  60. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_clients/_base.py +0 -0
  61. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_clients/_impit.py +0 -0
  62. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_compressors/__init__.py +0 -0
  63. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_compressors/_base.py +0 -0
  64. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_compressors/_brotli.py +0 -0
  65. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_compressors/_gzip.py +0 -0
  66. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/http_compressors/_resolve.py +0 -0
  67. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/py.typed +0 -0
  68. {apify_client-3.2.0 → apify_client-3.2.1b1}/src/apify_client/types.py +0 -0
@@ -2,6 +2,11 @@
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.2.1 - **not yet released**
7
+
8
+
9
+ <!-- git-cliff-unreleased-end -->
5
10
  ## [3.2.0](https://github.com/apify/apify-client-python/releases/tag/v3.2.0) (2026-09-03)
6
11
 
7
12
  ### 🚀 Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apify_client
3
- Version: 3.2.0
3
+ Version: 3.2.1b1
4
4
  Summary: Apify API client for Python
5
5
  Keywords: apify,api,client,automation,crawling,scraping
6
6
  Author: Apify Technologies s.r.o.
@@ -95,7 +95,7 @@ Description-Content-Type: text/markdown
95
95
  ```
96
96
 
97
97
  [Impit](https://github.com/apify/impit) is the default HTTP client and is installed automatically. To use the
98
- built-in [HTTPX](https://github.com/pydantic/httpx2) client instead, install the optional `httpx2` extra, which
98
+ built-in [HTTPX2](https://github.com/pydantic/httpx2) client instead, install the optional `httpx2` extra, which
99
99
  provides Pydantic's maintained continuation of HTTPX, and pass `http_client=Httpx2HttpClient()` to
100
100
  `ApifyClient.with_custom_http_client()`:
101
101
 
@@ -172,7 +172,7 @@ For a guided walkthrough — authenticating, running an Actor, and reading its r
172
172
  - **Tiered timeouts** — short / medium / long tiers picked per endpoint, overridable per call ([Timeouts](https://docs.apify.com/api/client/python/docs/concepts/timeouts)).
173
173
  - **Pagination and streaming** — iterate datasets, key-value store keys, or live logs without manual paging or buffering ([Pagination](https://docs.apify.com/api/client/python/docs/concepts/pagination), [Streaming](https://docs.apify.com/api/client/python/docs/concepts/streaming-resources)).
174
174
  - **Convenience methods** — `call()`, `wait_for_finish()`, nested resource access, and other shortcuts that hide platform quirks ([Convenience methods](https://docs.apify.com/api/client/python/docs/concepts/convenience-methods)).
175
- - **Pluggable HTTP layer** — use the default [Impit](https://github.com/apify/impit)-based client, opt in to the built-in [HTTPX](https://github.com/pydantic/httpx2) client, or plug in any custom implementation ([HTTP clients](https://docs.apify.com/api/client/python/docs/concepts/custom-http-clients)).
175
+ - **Pluggable HTTP layer** — use the default [Impit](https://github.com/apify/impit)-based client, opt in to the built-in [HTTPX2](https://github.com/pydantic/httpx2) client, or plug in any custom implementation ([HTTP clients](https://docs.apify.com/api/client/python/docs/concepts/custom-http-clients)).
176
176
  - **Structured errors** — every API error surfaces as an [`ApifyApiError`](https://docs.apify.com/api/client/python/reference/class/ApifyApiError) with HTTP-specific subclasses for precise handling ([Error handling](https://docs.apify.com/api/client/python/docs/concepts/error-handling)).
177
177
  - **Debug logging** — opt-in structured logging on the `apify_client` logger captures request URLs, status codes, retry attempts, and more ([Logging](https://docs.apify.com/api/client/python/docs/concepts/logging)).
178
178
 
@@ -58,7 +58,7 @@
58
58
  ```
59
59
 
60
60
  [Impit](https://github.com/apify/impit) is the default HTTP client and is installed automatically. To use the
61
- built-in [HTTPX](https://github.com/pydantic/httpx2) client instead, install the optional `httpx2` extra, which
61
+ built-in [HTTPX2](https://github.com/pydantic/httpx2) client instead, install the optional `httpx2` extra, which
62
62
  provides Pydantic's maintained continuation of HTTPX, and pass `http_client=Httpx2HttpClient()` to
63
63
  `ApifyClient.with_custom_http_client()`:
64
64
 
@@ -135,7 +135,7 @@ For a guided walkthrough — authenticating, running an Actor, and reading its r
135
135
  - **Tiered timeouts** — short / medium / long tiers picked per endpoint, overridable per call ([Timeouts](https://docs.apify.com/api/client/python/docs/concepts/timeouts)).
136
136
  - **Pagination and streaming** — iterate datasets, key-value store keys, or live logs without manual paging or buffering ([Pagination](https://docs.apify.com/api/client/python/docs/concepts/pagination), [Streaming](https://docs.apify.com/api/client/python/docs/concepts/streaming-resources)).
137
137
  - **Convenience methods** — `call()`, `wait_for_finish()`, nested resource access, and other shortcuts that hide platform quirks ([Convenience methods](https://docs.apify.com/api/client/python/docs/concepts/convenience-methods)).
138
- - **Pluggable HTTP layer** — use the default [Impit](https://github.com/apify/impit)-based client, opt in to the built-in [HTTPX](https://github.com/pydantic/httpx2) client, or plug in any custom implementation ([HTTP clients](https://docs.apify.com/api/client/python/docs/concepts/custom-http-clients)).
138
+ - **Pluggable HTTP layer** — use the default [Impit](https://github.com/apify/impit)-based client, opt in to the built-in [HTTPX2](https://github.com/pydantic/httpx2) client, or plug in any custom implementation ([HTTP clients](https://docs.apify.com/api/client/python/docs/concepts/custom-http-clients)).
139
139
  - **Structured errors** — every API error surfaces as an [`ApifyApiError`](https://docs.apify.com/api/client/python/reference/class/ApifyApiError) with HTTP-specific subclasses for precise handling ([Error handling](https://docs.apify.com/api/client/python/docs/concepts/error-handling)).
140
140
  - **Debug logging** — opt-in structured logging on the `apify_client` logger captures request URLs, status codes, retry attempts, and more ([Logging](https://docs.apify.com/api/client/python/docs/concepts/logging)).
141
141
 
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "apify_client"
7
- version = "3.2.0"
7
+ version = "3.2.1b1"
8
8
  description = "Apify API client for Python"
9
9
  license = "Apache-2.0"
10
10
  license-files = ["LICENSE"]
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "apify_client"
7
- version = "3.2.0"
7
+ version = "3.2.1b1"
8
8
  description = "Apify API client for Python"
9
9
  authors = [{ name = "Apify Technologies s.r.o.", email = "support@apify.com" }]
10
10
  license = "Apache-2.0"
@@ -7,7 +7,7 @@ import threading
7
7
  from asyncio import Task
8
8
  from datetime import UTC, datetime
9
9
  from threading import Thread
10
- from typing import TYPE_CHECKING, ClassVar, Self, cast
10
+ from typing import TYPE_CHECKING, ClassVar, Self
11
11
 
12
12
  from apify_client._docs import docs_group
13
13
 
@@ -79,10 +79,10 @@ class StreamedLogBase:
79
79
  """Guess the log level from the message."""
80
80
  # Using only levels explicitly mentioned in the logging module
81
81
  known_levels = ('CRITICAL', 'FATAL', 'ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', 'NOTSET')
82
+ level_names_to_levels = logging.getLevelNamesMapping()
82
83
  for level in known_levels:
83
84
  if level in message:
84
- # `getLevelName` returns an `int` when string is passed as input.
85
- return cast('int', logging.getLevelName(level))
85
+ return level_names_to_levels[level]
86
86
  # Unknown log level. Fall back to the default.
87
87
  return logging.INFO
88
88
 
@@ -5,7 +5,7 @@ from apify_client.http_clients._impit import ImpitHttpClient, ImpitHttpClientAsy
5
5
 
6
6
  _install_import_hook(__name__)
7
7
 
8
- # `httpx2` is an optional extra, so the import is wrapped in try_import. Accessing the HTTPX clients without the
8
+ # `httpx2` is an optional extra, so the import is wrapped in try_import. Accessing the HTTPX2 clients without the
9
9
  # extra installed raises a clear ImportError instead of failing at package import time.
10
10
  with _try_import(
11
11
  __name__,
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
- import httpx2 as httpx
5
+ import httpx2
6
6
  from typing_extensions import override
7
7
 
8
8
  from apify_client._consts import (
@@ -24,32 +24,32 @@ if TYPE_CHECKING:
24
24
 
25
25
 
26
26
  _PERMANENT_ERRORS = (
27
- # A request HTTPX rejects before sending it, e.g. one carrying an invalid header value.
28
- httpx.LocalProtocolError,
29
- # A URL scheme HTTPX refuses to speak, which repeating the request cannot change.
30
- httpx.UnsupportedProtocol,
27
+ # A request HTTPX2 rejects before sending it, e.g. one carrying an invalid header value.
28
+ httpx2.LocalProtocolError,
29
+ # A URL scheme HTTPX2 refuses to speak, which repeating the request cannot change.
30
+ httpx2.UnsupportedProtocol,
31
31
  # An over-long redirect chain is a routing loop, which repeating the request cannot break.
32
- httpx.TooManyRedirects,
32
+ httpx2.TooManyRedirects,
33
33
  # Only `Response.raise_for_status()` raises this, and the client never calls it - the shared pipeline decides on
34
34
  # status codes from the response itself.
35
- httpx.HTTPStatusError,
35
+ httpx2.HTTPStatusError,
36
36
  )
37
- """HTTPX errors that a retry cannot fix. Everything else in the `httpx.HTTPError` tree counts as transient."""
37
+ """HTTPX2 errors that a retry cannot fix. Everything else in the `httpx2.HTTPError` tree counts as transient."""
38
38
 
39
39
 
40
40
  @docs_group('HTTP clients')
41
41
  class Httpx2HttpClient(HttpClient):
42
- """Synchronous HTTP client for the Apify API built on top of [HTTPX](https://github.com/pydantic/httpx2).
42
+ """Synchronous HTTP client for the Apify API built on top of [HTTPX2](https://github.com/pydantic/httpx2).
43
43
 
44
- This client wraps `httpx.Client` and adds automatic retries with exponential backoff for rate-limited
44
+ This client wraps `httpx2.Client` and adds automatic retries with exponential backoff for rate-limited
45
45
  (HTTP 429) and server error (HTTP 5xx) responses.
46
46
 
47
- HTTPX applies a request timeout to each socket operation rather than to the request as a whole, so a response
47
+ HTTPX2 applies a request timeout to each socket operation rather than to the request as a whole, so a response
48
48
  whose body arrives slowly keeps resetting it and can outlast both the requested timeout and `timeout_max`. The
49
49
  default Impit client enforces the same value as a deadline for the whole request, body included.
50
50
 
51
51
  Requires the `httpx2` extra: `pip install "apify-client[httpx2]"`. The `httpx2` package is Pydantic's maintained
52
- continuation of HTTPX, which this module imports under the `httpx` name.
52
+ continuation of HTTPX.
53
53
  """
54
54
 
55
55
  def __init__(
@@ -66,7 +66,7 @@ class Httpx2HttpClient(HttpClient):
66
66
  headers: dict[str, str] | None = None,
67
67
  http_compressor: HttpCompressor | None = None,
68
68
  ) -> None:
69
- """Initialize the HTTPX-based synchronous HTTP client.
69
+ """Initialize the HTTPX2-based synchronous HTTP client.
70
70
 
71
71
  Args:
72
72
  token: Apify API token for authentication.
@@ -93,27 +93,27 @@ class Httpx2HttpClient(HttpClient):
93
93
  http_compressor=http_compressor,
94
94
  )
95
95
 
96
- self._httpx_client = httpx.Client(
96
+ self._httpx2_client = httpx2.Client(
97
97
  follow_redirects=True,
98
98
  event_hooks={'response': [self._clear_response_cookies]},
99
99
  )
100
100
 
101
101
  @override
102
102
  def is_timeout_error(self, exc: Exception) -> bool:
103
- return super().is_timeout_error(exc) or isinstance(exc, httpx.TimeoutException)
103
+ return super().is_timeout_error(exc) or isinstance(exc, httpx2.TimeoutException)
104
104
 
105
105
  @override
106
106
  def is_retryable_transport_error(self, exc: Exception) -> bool:
107
- # Every error from HTTPX's own hierarchy counts as transient except the permanently-failing types listed in
108
- # `_PERMANENT_ERRORS`. Retrying is the default so a subclass HTTPX adds later is retried rather than
107
+ # Every error from HTTPX2's own hierarchy counts as transient except the permanently-failing types listed in
108
+ # `_PERMANENT_ERRORS`. Retrying is the default so a subclass HTTPX2 adds later is retried rather than
109
109
  # silently treated as fatal. HTTP status code errors are handled by the shared pipeline based on the
110
110
  # response status code, not here.
111
- return isinstance(exc, httpx.HTTPError) and not isinstance(exc, _PERMANENT_ERRORS)
111
+ return isinstance(exc, httpx2.HTTPError) and not isinstance(exc, _PERMANENT_ERRORS)
112
112
 
113
113
  @override
114
114
  def close(self) -> None:
115
- """Close the underlying HTTPX connection pool."""
116
- self._httpx_client.close()
115
+ """Close the underlying HTTPX2 connection pool."""
116
+ self._httpx2_client.close()
117
117
 
118
118
  @override
119
119
  def send_request(
@@ -125,8 +125,8 @@ class Httpx2HttpClient(HttpClient):
125
125
  content: bytes | None,
126
126
  timeout: float | None,
127
127
  stream: bool,
128
- ) -> httpx.Response:
129
- request = self._httpx_client.build_request(
128
+ ) -> httpx2.Response:
129
+ request = self._httpx2_client.build_request(
130
130
  method=method,
131
131
  url=url,
132
132
  headers=headers,
@@ -134,26 +134,26 @@ class Httpx2HttpClient(HttpClient):
134
134
  timeout=timeout,
135
135
  )
136
136
  _restore_explicit_cookie_header(request, headers)
137
- return self._httpx_client.send(request, stream=stream)
137
+ return self._httpx2_client.send(request, stream=stream)
138
138
 
139
- def _clear_response_cookies(self, _response: httpx.Response) -> None:
140
- """Prevent HTTPX's shared cookie jar from leaking server cookies into later API requests."""
141
- self._httpx_client.cookies.clear()
139
+ def _clear_response_cookies(self, _response: httpx2.Response) -> None:
140
+ """Prevent HTTPX2's shared cookie jar from leaking server cookies into later API requests."""
141
+ self._httpx2_client.cookies.clear()
142
142
 
143
143
 
144
144
  @docs_group('HTTP clients')
145
145
  class Httpx2HttpClientAsync(HttpClientAsync):
146
- """Asynchronous HTTP client for the Apify API built on top of [HTTPX](https://github.com/pydantic/httpx2).
146
+ """Asynchronous HTTP client for the Apify API built on top of [HTTPX2](https://github.com/pydantic/httpx2).
147
147
 
148
- This client wraps `httpx.AsyncClient` and adds automatic retries with exponential backoff for rate-limited
148
+ This client wraps `httpx2.AsyncClient` and adds automatic retries with exponential backoff for rate-limited
149
149
  (HTTP 429) and server error (HTTP 5xx) responses.
150
150
 
151
- HTTPX applies a request timeout to each socket operation rather than to the request as a whole, so a response
151
+ HTTPX2 applies a request timeout to each socket operation rather than to the request as a whole, so a response
152
152
  whose body arrives slowly keeps resetting it and can outlast both the requested timeout and `timeout_max`. The
153
153
  default Impit client enforces the same value as a deadline for the whole request, body included.
154
154
 
155
155
  Requires the `httpx2` extra: `pip install "apify-client[httpx2]"`. The `httpx2` package is Pydantic's maintained
156
- continuation of HTTPX, which this module imports under the `httpx` name.
156
+ continuation of HTTPX.
157
157
  """
158
158
 
159
159
  def __init__(
@@ -170,7 +170,7 @@ class Httpx2HttpClientAsync(HttpClientAsync):
170
170
  headers: dict[str, str] | None = None,
171
171
  http_compressor: HttpCompressor | None = None,
172
172
  ) -> None:
173
- """Initialize the HTTPX-based asynchronous HTTP client.
173
+ """Initialize the HTTPX2-based asynchronous HTTP client.
174
174
 
175
175
  Args:
176
176
  token: Apify API token for authentication.
@@ -197,27 +197,27 @@ class Httpx2HttpClientAsync(HttpClientAsync):
197
197
  http_compressor=http_compressor,
198
198
  )
199
199
 
200
- self._httpx_async_client = httpx.AsyncClient(
200
+ self._httpx2_async_client = httpx2.AsyncClient(
201
201
  follow_redirects=True,
202
202
  event_hooks={'response': [self._clear_response_cookies]},
203
203
  )
204
204
 
205
205
  @override
206
206
  def is_timeout_error(self, exc: Exception) -> bool:
207
- return super().is_timeout_error(exc) or isinstance(exc, httpx.TimeoutException)
207
+ return super().is_timeout_error(exc) or isinstance(exc, httpx2.TimeoutException)
208
208
 
209
209
  @override
210
210
  def is_retryable_transport_error(self, exc: Exception) -> bool:
211
- # Every error from HTTPX's own hierarchy counts as transient except the permanently-failing types listed in
212
- # `_PERMANENT_ERRORS`. Retrying is the default so a subclass HTTPX adds later is retried rather than
211
+ # Every error from HTTPX2's own hierarchy counts as transient except the permanently-failing types listed in
212
+ # `_PERMANENT_ERRORS`. Retrying is the default so a subclass HTTPX2 adds later is retried rather than
213
213
  # silently treated as fatal. HTTP status code errors are handled by the shared pipeline based on the
214
214
  # response status code, not here.
215
- return isinstance(exc, httpx.HTTPError) and not isinstance(exc, _PERMANENT_ERRORS)
215
+ return isinstance(exc, httpx2.HTTPError) and not isinstance(exc, _PERMANENT_ERRORS)
216
216
 
217
217
  @override
218
218
  async def aclose(self) -> None:
219
- """Close the underlying asynchronous HTTPX connection pool."""
220
- await self._httpx_async_client.aclose()
219
+ """Close the underlying asynchronous HTTPX2 connection pool."""
220
+ await self._httpx2_async_client.aclose()
221
221
 
222
222
  @override
223
223
  async def send_request(
@@ -229,8 +229,8 @@ class Httpx2HttpClientAsync(HttpClientAsync):
229
229
  content: bytes | None,
230
230
  timeout: float | None,
231
231
  stream: bool,
232
- ) -> httpx.Response:
233
- request = self._httpx_async_client.build_request(
232
+ ) -> httpx2.Response:
233
+ request = self._httpx2_async_client.build_request(
234
234
  method=method,
235
235
  url=url,
236
236
  headers=headers,
@@ -238,17 +238,17 @@ class Httpx2HttpClientAsync(HttpClientAsync):
238
238
  timeout=timeout,
239
239
  )
240
240
  _restore_explicit_cookie_header(request, headers)
241
- return await self._httpx_async_client.send(request, stream=stream)
241
+ return await self._httpx2_async_client.send(request, stream=stream)
242
242
 
243
- async def _clear_response_cookies(self, _response: httpx.Response) -> None:
244
- """Prevent HTTPX's shared cookie jar from leaking server cookies into later API requests."""
245
- self._httpx_async_client.cookies.clear()
243
+ async def _clear_response_cookies(self, _response: httpx2.Response) -> None:
244
+ """Prevent HTTPX2's shared cookie jar from leaking server cookies into later API requests."""
245
+ self._httpx2_async_client.cookies.clear()
246
246
 
247
247
 
248
- def _restore_explicit_cookie_header(request: httpx.Request, headers: dict[str, str]) -> None:
249
- """Keep only cookies explicitly supplied for this request, never cookies from HTTPX's shared jar.
248
+ def _restore_explicit_cookie_header(request: httpx2.Request, headers: dict[str, str]) -> None:
249
+ """Keep only cookies explicitly supplied for this request, never cookies from HTTPX2's shared jar.
250
250
 
251
- HTTPX drops the `Cookie` header when it builds a redirect request and rebuilds it from the jar, so an explicit
251
+ HTTPX2 drops the `Cookie` header when it builds a redirect request and rebuilds it from the jar, so an explicit
252
252
  cookie only reaches the first hop of a redirected request.
253
253
  """
254
254
  explicit_cookie = next((value for key, value in headers.items() if key.lower() == 'cookie'), None)
File without changes