|
1 | 1 | --- |
2 | | -id: custom-http-client-httpx |
3 | | -title: Build a custom HTTP client with AIOHTTP |
4 | | -description: Implement the asynchronous HTTP client contract with AIOHTTP. |
| 2 | +id: custom-http-client |
| 3 | +title: Build a custom HTTP client |
| 4 | +description: Implement the HTTP client contract with AIOHTTP and requests. |
5 | 5 | --- |
6 | 6 |
|
7 | 7 | import ApiLink from '@theme/ApiLink'; |
8 | 8 | import CodeBlock from '@theme/CodeBlock'; |
| 9 | +import Tabs from '@theme/Tabs'; |
| 10 | +import TabItem from '@theme/TabItem'; |
9 | 11 |
|
10 | | -import CustomHttpClientExample from '!!raw-loader!./code/05_custom_http_client_async.py'; |
| 12 | +import CustomHttpClientAsyncExample from '!!raw-loader!./code/05_custom_http_client_async.py'; |
| 13 | +import CustomHttpClientSyncExample from '!!raw-loader!./code/05_custom_http_client_sync.py'; |
11 | 14 |
|
12 | | -This guide implements a custom <ApiLink to="class/HttpClientAsync">`HttpClientAsync`</ApiLink> using |
13 | | -[AIOHTTP](https://docs.aiohttp.org/). It demonstrates how to integrate a transport that does not already implement the |
14 | | -<ApiLink to="class/HttpResponse">`HttpResponse`</ApiLink> protocol. Because AIOHTTP is asynchronous, this guide focuses |
15 | | -on the async client contract; a synchronous custom transport would implement <ApiLink to="class/HttpClient">`HttpClient`</ApiLink> |
16 | | -in the same role. |
| 15 | +This guide implements a custom <ApiLink to="class/HttpClientAsync">`HttpClientAsync`</ApiLink> with |
| 16 | +[AIOHTTP](https://docs.aiohttp.org/) and a custom <ApiLink to="class/HttpClient">`HttpClient`</ApiLink> with |
| 17 | +[requests](https://requests.readthedocs.io/). Neither library satisfies the |
| 18 | +<ApiLink to="class/HttpResponse">`HttpResponse`</ApiLink> protocol, so both examples also show how to adapt a |
| 19 | +foreign response API. |
17 | 20 |
|
18 | 21 | For an overview of the architecture and the built-in Impit and HTTPX implementations, see |
19 | | -[HTTP clients](/api/client/python/docs/concepts/custom-http-clients). |
| 22 | +[HTTP clients](../02_concepts/10_custom_http_clients.mdx). |
20 | 23 |
|
21 | 24 | ## Installation |
22 | 25 |
|
23 | | -Install AIOHTTP alongside the Apify client. AIOHTTP is only used by this custom implementation and is not an |
24 | | -`apify-client` extra: |
| 26 | +Install the transport alongside the Apify client. Neither AIOHTTP nor requests is an `apify-client` extra: |
25 | 27 |
|
26 | 28 | ```bash |
27 | | -pip install apify-client aiohttp |
28 | | -# or |
29 | | -uv add apify-client aiohttp |
| 29 | +pip install apify-client aiohttp # for the asynchronous client |
| 30 | +pip install apify-client requests # for the synchronous client |
30 | 31 | ``` |
31 | 32 |
|
32 | 33 | ## Implementation |
33 | 34 |
|
34 | | -The example has three parts: |
35 | | - |
36 | | -1. `AiohttpResponse` adapts AIOHTTP's response API to the <ApiLink to="class/HttpResponse">`HttpResponse`</ApiLink> |
37 | | - protocol expected by resource clients. |
38 | | -2. `AiohttpHttpClient` implements the abstract transport, error-classification, timeout-classification, and lifecycle |
39 | | - hooks. It inherits request preparation, retry handling, timeout growth, and API error conversion from |
40 | | - <ApiLink to="class/HttpClientAsync">`HttpClientAsync`</ApiLink>. |
41 | | -3. <ApiLink to="class/ApifyClientAsync#with_custom_http_client">`ApifyClientAsync.with_custom_http_client()`</ApiLink> |
42 | | - connects the implementation to the resource clients and applies the API token. The async context manager closes |
43 | | - the AIOHTTP session at shutdown. |
44 | | - |
45 | | -<CodeBlock className="language-python"> |
46 | | - {CustomHttpClientExample} |
47 | | -</CodeBlock> |
| 35 | +Each example has three parts: |
| 36 | + |
| 37 | +1. The response adapter, `AiohttpResponse` or `RequestsResponse`, maps the library's own response onto the |
| 38 | + <ApiLink to="class/HttpResponse">`HttpResponse`</ApiLink> protocol that resource clients expect. |
| 39 | +2. The client, `AiohttpHttpClient` or `RequestsHttpClient`, implements the transport, error-classification, |
| 40 | + timeout-classification, and lifecycle hooks. It inherits request preparation, retry handling, timeout growth, |
| 41 | + and API error conversion from its base class. |
| 42 | +3. `with_custom_http_client()` connects the implementation to the resource clients and applies the API token. The |
| 43 | + context manager closes the session at shutdown. |
| 44 | + |
| 45 | +<Tabs> |
| 46 | + <TabItem value="AsyncExample" label="Async client" default> |
| 47 | + <CodeBlock className="language-python"> |
| 48 | + {CustomHttpClientAsyncExample} |
| 49 | + </CodeBlock> |
| 50 | + </TabItem> |
| 51 | + <TabItem value="SyncExample" label="Sync client"> |
| 52 | + <CodeBlock className="language-python"> |
| 53 | + {CustomHttpClientSyncExample} |
| 54 | + </CodeBlock> |
| 55 | + </TabItem> |
| 56 | +</Tabs> |
48 | 57 |
|
49 | 58 | :::warning |
50 | | -This is a compact integration example, not a replacement for all built-in client behavior. A production custom client |
51 | | -should account for transport-specific details such as proxy configuration, TLS settings, redirects, and response |
52 | | -resource cleanup. The shared base provides retries, logging, statistics, timeout growth, and API error conversion. |
| 59 | +These are compact integration examples, not a replacement for all built-in client behavior. A production custom |
| 60 | +client should account for transport-specific details such as proxy configuration, TLS settings, redirects, and |
| 61 | +response resource cleanup. The shared base provides retries, logging, statistics, timeout growth, and API error |
| 62 | +conversion. |
53 | 63 | ::: |
0 commit comments