Implementing Custom HTTP Clients
Relevant source files
The following files were used as context for generating this wiki page:
The Resend Python SDK provides a flexible architecture for handling network requests through replaceable HTTP clients. This system allows you to override default networking behavior, adjust timeouts, or use specific networking libraries for both synchronous and asynchronous operations.
Architecture Overview
The SDK separates request logic from transport implementation. High-level modules use Request or AsyncRequest objects to define API calls, which then delegate the actual network transmission to a configured client object.
This diagram shows the relationship between the SDK request logic and the interchangeable transport implementations.
Sources: resend/request.py:79-106, resend/async_request.py:80-112
Synchronous HTTP Client Implementation
To implement a custom synchronous client, you must create a subclass of HTTPClient. This interface requires a request method that returns a tuple containing the response body, status code, and headers.
HTTPClient Interface Requirements
| Component | Description |
|---|---|
| Method | request(self, method, url, headers, json, files, data) |
| Return Type | Tuple[bytes, int, Dict[str, str]] |
| Default | RequestsClient (built on the requests library) |
Sources: resend/http_client.py:1-17, resend/__init__.py:192-193
from resend.http_client import HTTPClient
class MyCustomClient(HTTPClient):
def request(self, method, url, **kwargs):
# Implementation logic here
return b"{}", 200, {"Content-Type": "application/json"}
import resend
resend.default_http_client = MyCustomClient()
Sources: resend/http_client.py:5-17, resend/__init__.py:193
Asynchronous HTTP Client Implementation
The SDK supports asynchronous operations through the AsyncHTTPClient interface. The SDK automatically detects httpx if installed and uses HTTPXClient as the default async transport.
Client Selection Logic
For asynchronous requests, the SDK selects a client based on this priority order:
resend.default_async_http_client(Dedicated async setting).resend.default_http_client(If the assigned object implementsAsyncHTTPClient).resend._auto_async_http_client(AutomaticHTTPXClientdetection).
This sequence illustrates how the SDK resolves which client to use for asynchronous operations.
Sources: resend/async_request.py:82-96, README.md:104-111
Configuration and Overrides
You configure clients by assigning instances to the package-level variables in resend.
- Sync Override: Assign to
resend.default_http_client. - Async Override: Assign to
resend.default_async_http_client.
Error Handling in Clients
When a custom client throws an exception, the Request and AsyncRequest classes catch it and wrap it in a ResendError with error_type="HttpClientError". This ensures the SDK provides a consistent error interface regardless of the underlying transport.
Sources: resend/request.py:108-114, resend/async_request.py:114-121
Conclusion
Implementing custom HTTP clients allows for deep integration with existing application stacks and fine-grained control over network behavior. By adhering to the HTTPClient or AsyncHTTPClient interfaces, you can replace the default requests or httpx transports while maintaining the SDK's standard error handling and request processing logic.