You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+11-2Lines changed: 11 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -57,6 +57,15 @@
57
57
uv add "apify-client[brotli]"
58
58
```
59
59
60
+
[Impit](https://github.com/apify/impit) is the default HTTP client and is installed automatically. To use the
61
+
built-in [HTTPX](https://www.python-httpx.org/) client instead, install its optional extra:
62
+
63
+
```bash
64
+
pip install "apify-client[httpx]"
65
+
# or
66
+
uv add "apify-client[httpx]"
67
+
```
68
+
60
69
- From [conda-forge](https://anaconda.org/conda-forge/apify-client), it can be installed with [conda](https://docs.conda.io/en/latest/):
61
70
62
71
```bash
@@ -124,7 +133,7 @@ For a guided walkthrough — authenticating, running an Actor, and reading its r
124
133
- **Tiered timeouts** — short / medium / long tiers picked per endpoint, overridable per call ([Timeouts](https://docs.apify.com/api/client/python/docs/concepts/timeouts)).
125
134
- **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)).
126
135
- **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)).
127
-
- **Pluggable HTTP layer** — swap the default [Impit](https://github.com/apify/impit)-based HTTP clientfor`httpx`, `requests`, `aiohttp`, or any custom implementation ([Custom HTTP clients](https://docs.apify.com/api/client/python/docs/concepts/custom-http-clients)).
136
+
- **Pluggable HTTP layer** — use the default [Impit](https://github.com/apify/impit)-based client, opt in to the built-in [HTTPX](https://www.python-httpx.org/) client, or provide any custom implementation ([HTTP clients](https://docs.apify.com/api/client/python/docs/concepts/custom-http-clients)).
128
137
- **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)).
129
138
- **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)).
130
139
@@ -192,7 +201,7 @@ The full documentation lives at **[docs.apify.com/api/client/python](https://doc
192
201
| [Introduction](https://docs.apify.com/api/client/python/docs) | Overview, prerequisites, and a tour of the client. |
193
202
| [Quick start](https://docs.apify.com/api/client/python/docs/quick-start) | Authenticate, run an Actor, and fetch its results step by step. |
| [Guides](https://docs.apify.com/api/client/python/docs/guides/passing-input-to-actor) | Pass input to an Actor, manage tasks for reusable input, retrieve Actor data, integrate with data libraries (e.g. Pandas), use HTTPX as the HTTP client. |
204
+
| [Guides](https://docs.apify.com/api/client/python/docs/guides/passing-input-to-actor) | Pass input to an Actor, manage tasks for reusable input, retrieve Actor data, integrate with data libraries (e.g. Pandas), build a custom HTTP client. |
196
205
| [Upgrading](https://docs.apify.com/api/client/python/docs/upgrading/upgrading-to-v3) | Migrating between major versions. |
197
206
| [API reference](https://docs.apify.com/api/client/python/reference) | Generated reference for every class, method, and model. |
198
207
| [Changelog](https://docs.apify.com/api/client/python/docs/changelog) | Release history and breaking changes. |
The Apify API client uses a pluggable HTTP client architecture. By default, it ships with an [Impit](https://github.com/apify/impit)-based HTTP client that handles retries, timeouts, passing headers, and more. You can replace it with your own implementation for use cases like custom logging, proxying, request modification, or integrating with a different HTTP library.
22
+
The Apify API client uses a pluggable HTTP layer. It ships with an [Impit](https://github.com/apify/impit)-based default,
23
+
offers [HTTPX](https://www.python-httpx.org/) as an optional built-in alternative, and accepts fully custom synchronous
24
+
or asynchronous implementations.
21
25
22
26
## Default HTTP client
23
27
24
28
When you create an <ApiLinkto="class/ApifyClient">`ApifyClient`</ApiLink> or <ApiLinkto="class/ApifyClientAsync">`ApifyClientAsync`</ApiLink> instance, it automatically uses the built-in <ApiLinkto="class/ImpitHttpClient">`ImpitHttpClient`</ApiLink> (or <ApiLinkto="class/ImpitHttpClientAsync">`ImpitHttpClientAsync`</ApiLink>). This default client provides:
25
29
26
30
- Automatic retries with exponential backoff for network errors, HTTP 429, and HTTP 5xx responses.
27
31
- Configurable timeouts.
28
-
-Preparing request data and headers according to the API requirements, including authentication.
29
-
-Collecting requests statistics for monitoring and debugging.
32
+
-Request compression and preparation of API-compatible data, query parameters, and headers, including authentication.
33
+
-API error handling, structured logging, and request statistics.
30
34
31
35
You can configure the default client through the <ApiLinkto="class/ApifyClient">`ApifyClient`</ApiLink> or <ApiLinkto="class/ApifyClientAsync">`ApifyClientAsync`</ApiLink> constructor:
32
36
@@ -43,35 +47,94 @@ You can configure the default client through the <ApiLink to="class/ApifyClient"
43
47
</TabItem>
44
48
</Tabs>
45
49
50
+
## Built-in HTTPX client
51
+
52
+
The package also provides <ApiLinkto="class/HttpxHttpClient">`HttpxHttpClient`</ApiLink> and
53
+
<ApiLinkto="class/HttpxHttpClientAsync">`HttpxHttpClientAsync`</ApiLink>. They use the same request preparation,
54
+
compression, retry policy, timeout tiers and growth, error handling, logging, and statistics as the default Impit clients, with
55
+
[HTTPX](https://www.python-httpx.org/) as the transport.
56
+
57
+
HTTPX is an optional dependency. Install `apify-client[httpx]`, then pass the appropriate client to
Configure retries, timeout tiers, default headers, and compression on the HTTPX client instance. The token passed to
81
+
`with_custom_http_client` is applied automatically unless the HTTP client already has an `Authorization` header.
82
+
The examples use the clients as context managers so their connection pools are closed deterministically. If a context
83
+
manager does not fit your application's lifecycle, call `close()` on `HttpxHttpClient` or `await aclose()` on
84
+
`HttpxHttpClientAsync` during shutdown.
85
+
86
+
Timeout values are passed to the selected transport. Impit treats them as whole-request timeouts, while HTTPX applies
87
+
its connect, read, write, and pool timeout semantics. In particular, an HTTPX read timeout limits inactivity between
88
+
chunks rather than the total duration of a streamed response. The `no_timeout` option disables HTTPX's timeouts.
89
+
46
90
## Architecture
47
91
48
-
The HTTP client system is built on two key abstractions:
92
+
Internally, the HTTP client hierarchy has three layers:
93
+
94
+
- A common internal base contains configuration and utilities shared by synchronous and asynchronous clients, including
95
+
headers, request-body preparation, parameters, compression, and timeout tiers. It is not a public extension point.
96
+
- <ApiLinkto="class/HttpClient">`HttpClient`</ApiLink> and <ApiLinkto="class/HttpClientAsync">`HttpClientAsync`</ApiLink>
97
+
add the synchronous or asynchronous request pipeline, retry loop, transport hooks, and lifecycle interface.
98
+
- The built-in Impit and HTTPX classes inherit directly from the corresponding sync or async class and adapt the
99
+
underlying transport.
100
+
101
+
`HttpClient.is_timeout_error(exc)` and `HttpClientAsync.is_timeout_error(exc)` provide the public, transport-neutral way
102
+
to determine whether an exception is a timeout. Their shared implementation recognizes Python's `TimeoutError`;
103
+
transport adapters override it when their HTTP library defines additional timeout exception types. This lets
104
+
higher-level features such as streamed logs classify timeouts without depending on Impit, HTTPX, or private
105
+
implementation details.
106
+
107
+
Responses use one separate abstraction:
49
108
50
-
- <ApiLinkto="class/HttpClient">`HttpClient`</ApiLink> / <ApiLinkto="class/HttpClientAsync">`HttpClientAsync`</ApiLink> - Abstract base classes that define the interface. Extend one of these to create a custom HTTP client by implementing the `call` method.
51
109
- <ApiLinkto="class/HttpResponse">`HttpResponse`</ApiLink> - A [runtime-checkable protocol](https://docs.python.org/3/library/typing.html#typing.runtime_checkable) that defines the expected response shape. Any object with the required attributes and methods satisfies the protocol — no inheritance needed.
52
110
53
111
To plug in your custom implementation, use the <ApiLinkto="class/ApifyClient#with_custom_http_client">`ApifyClient.with_custom_http_client`</ApiLink> class method.
54
112
55
-
All of these are available as top-level imports from the `apify_client` package:
113
+
The built-in Impit and HTTPX classes are thin transport adapters over the request implementation in `HttpClient` and
114
+
`HttpClientAsync`. Custom transport adapters implement the request, error-classification, and lifecycle hooks. They
115
+
inherit request construction, retries, timeout growth, API error conversion, logging, and statistics from the base.
116
+
117
+
All of these are available from the `apify_client.http_clients` module:
56
118
57
119
<CodeBlockclassName="language-python">
58
120
{ArchitectureImportsExample}
59
121
</CodeBlock>
60
122
61
-
### The call method
123
+
### The transport contract
62
124
63
-
The `call` method receives all the information needed to make an HTTP request:
125
+
The public `call` method provides the shared request pipeline. A concrete transport implements these hooks:
-`params` - Query parameters to append to the URL.
69
-
-`data` - Raw request body (mutually exclusive with `json`).
70
-
-`json` - JSON-serializable request body (mutually exclusive with `data`).
71
-
-`stream` - Whether to stream the response body.
72
-
-`timeout` - Timeout for the request as a `timedelta`.
127
+
-`send_request(...)` sends one prepared request and returns an `HttpResponse`. The inherited `call` needs it, so
128
+
every transport adapter has to implement it.
129
+
-`is_retryable_transport_error(exc)` classifies transport failures for the shared retry loop. The default classifies
130
+
nothing as retryable, so a transport that skips it gives up on the first connection failure.
131
+
-`is_timeout_error(exc)` identifies transport-specific timeout exceptions for higher-level client features. The
132
+
default recognizes Python's `TimeoutError`.
133
+
-`close()` or `aclose()` closes resources owned by the transport. The default does nothing, which is correct for a
134
+
transport that owns no pool or session.
73
135
74
-
It must return an object satisfying the <ApiLinkto="class/HttpResponse">`HttpResponse`</ApiLink> protocol.
136
+
The `@override` decorators in the built-in Impit and HTTPX adapters make these implementations explicit and allow type
137
+
checkers to catch misspelled or incompatible overrides.
75
138
76
139
### The HTTP response protocol
77
140
@@ -93,6 +156,10 @@ It must return an object satisfying the <ApiLink to="class/HttpResponse">`HttpRe
93
156
94
157
:::note
95
158
Many HTTP libraries, including our default [Impit](https://github.com/apify/impit) or for example [HTTPX](https://www.python-httpx.org/) already satisfy this protocol out of the box.
159
+
160
+
For a streamed response, consume the body inside its context manager with `iter_bytes()` / `aiter_bytes()`, or call
161
+
`read()` / `aread()` before accessing `content`. Some transports, including HTTPX, intentionally reject `content` on
162
+
an unread streamed response.
96
163
:::
97
164
98
165
### Plugging it in
@@ -115,18 +182,23 @@ Use the <ApiLink to="class/ApifyClient#with_custom_http_client">`ApifyClient.wit
115
182
After that, all API calls made through the client will go through your custom HTTP client.
116
183
117
184
:::warning
118
-
When using a custom HTTP client, you are responsible for constructing the request, handling retries, timeouts, and errors yourself. The default retry logic is not applied.
185
+
If you override `call` itself, your implementation becomes responsible for request preparation, retries, timeouts, API
186
+
error conversion, logging, and statistics. Implementing the transport hooks and inheriting `call` keeps the shared
187
+
behavior.
119
188
:::
120
189
121
190
## Use cases
122
191
123
-
Custom HTTP clients might be useful when you need to:
192
+
Custom HTTP clients might be useful when the built-in Impit and HTTPX clients do not cover your requirements, for
193
+
example when you need to:
124
194
125
-
-**Use a different HTTP library** - Swap Impit for [httpx](https://www.python-httpx.org/), [requests](https://requests.readthedocs.io/), or [aiohttp](https://docs.aiohttp.org/).
195
+
-**Use a different HTTP library** - Integrate [requests](https://requests.readthedocs.io/), [aiohttp](https://docs.aiohttp.org/), or another transport.
126
196
-**Route through a proxy** - Add proxy support or request routing.
127
197
-**Implement custom retry logic** - Use different backoff strategies or retry conditions.
128
198
-**Log requests and responses** - Track API calls for debugging or auditing.
129
199
-**Modify requests** - Add custom fields, modify the body, or change headers.
130
200
-**Collect custom metrics** - Measure request latency, track error rates, or count API calls.
131
201
132
-
For a step-by-step walkthrough of building a custom HTTP client, see the [Using HTTPX as the HTTP client](/api/client/python/docs/guides/custom-http-client-httpx) guide.
202
+
For complete synchronous and asynchronous implementations over a transport with a different response API, see
203
+
[Build a custom HTTP client](../03_guides/05_custom_http_client.mdx). You can also refer to the
204
+
<ApiLinkto="class/HttpClient">`HttpClient` API reference</ApiLink> for the synchronous contract.
0 commit comments