Backend¶
A backend is the adapter layer that lets ahttp_client drive different third-party HTTP client libraries through one common interface. A backend is never instantiated directly; the HTTP client class is passed to a session instead, and the matching backend is selected automatically.
import aiohttp
import httpx
# Selects AiohttpBackend
aiohttp_service = GithubService("https://api.github.com", aiohttp.ClientSession)
# Selects HttpXAsyncSession
httpx_service = GithubService("https://api.github.com", httpx.AsyncClient)
Supported Backends¶
Library |
Session class |
Backend class |
Extra dependency |
|---|---|---|---|
aiohttp |
aiohttp.ClientSession |
pip install aiohttp |
|
httpx (async) |
httpx.AsyncClient |
pip install httpx |
|
httpx (sync) |
httpx.Client |
pip install httpx |
|
requests (sync) |
requests.Session |
pip install requests |
AsyncSession takes aiohttp.ClientSession, httpx.AsyncClient, or any other registered asynchronous session class. Session takes httpx.Client, requests.Session, or any other registered synchronous session class.
Note
An optional dependency (aiohttp, httpx, or requests) that is not installed is simply skipped: ahttp_client.backend only exports the backends whose third-party package is importable.
How Backend Selection Works¶
BaseBackend keeps a registry mapping third-party session classes to their backend classes.
A concrete backend adds itself to that registry automatically, through __init_subclass__, as soon as both session_cls and response_cls are defined on it.
When a session such as AsyncSession(base_url, aiohttp.ClientSession) is created, it calls AsyncBackend.from_session(aiohttp.ClientSession, base_url=base_url, **kwargs), which looks up the registered backend for that session class and instantiates it. This is why the session=… argument on AsyncSession/Session is simply the third-party client class, not a backend instance.
Writing a Custom Backend¶
Subclass AsyncBackend for an asynchronous client, or SyncBackend for a synchronous one, and set session_cls/response_cls on it.
The remaining work is implementing a handful of abstract methods:
get_request_kwargs turns a
RequestCoreinto that client’s request keyword arguments.response_status, response_headers, response_url, response_data, response_text, response_json, and response_closed read the status code, headers, URL, body, and closed state off that client’s response object.
response_close and session_close/session_closed handle closing a response and the session itself.
session_request, session_get, session_post, session_options, session_delete, session_patch, and session_put issue each HTTP method against the underlying session.
1from ahttp_client.backend import AsyncBackend
2
3class MyClientBackend(AsyncBackend):
4 session_cls = my_client.Session
5 response_cls = my_client.Response
6
7 def get_request_kwargs(self, request_obj):
8 ...
9
10 def response_status(self, response_obj) -> int:
11 return response_obj.status_code
12
13 # ... remaining abstract methods
Once MyClientBackend is imported, AsyncSession(base_url, my_client.Session) resolves to it automatically; no further registration is required.
Reference¶
- class BaseBackend¶
Base adapter for a supported HTTP client library.
A backend creates the client session, converts
RequestCorevalues to client-specific keyword arguments, and exposes a common response interface. Subclasses that define bothsession_clsandresponse_clsare registered automatically.- classmethod from_session(session: type[Any], **kwargs: Any) _BackendT¶
Create the backend registered for an HTTP client session class.
- abstractmethod get_request_kwargs(request_obj: RequestCore[Any, Any]) dict[str, Any]¶
Convert a request descriptor into client-specific request arguments.
- abstractmethod response_close(response_obj: Any) None | Awaitable[None]¶
Close a client response object.
- abstractmethod response_closed(response_obj: Any) bool | None¶
Return response close state, or
Noneif it is unavailable.
- abstractmethod response_headers(response_obj: Any) dict[str, Any]¶
Return response headers as a dictionary.
- abstractmethod response_json(response_obj: Any, json_parser: Callable[..., Any] | None = None, json_kwargs: dict[str, Any] | None = None) Any | None¶
Parse the response body as JSON using an optional custom parser.
- abstractmethod response_status(response_obj: Any) int¶
Return the HTTP status code from a client response.
- class AsyncBackend¶
Bases:
BaseBackend,ABCBase adapter contract for asynchronous HTTP client libraries.
- async pre_read_response(response_obj: Any) None¶
Read a response before it is exposed through
Response.Backends that require eager reads can override this method.
- abstractmethod async session_delete(path: str, **kwargs: Any) Any¶
Make an asynchronous
DELETErequest.
- abstractmethod async session_options(path: str, **kwargs: Any) Any¶
Make an asynchronous
OPTIONSrequest.
- class SyncBackend¶
Bases:
BaseBackend,ABCBase adapter contract for synchronous HTTP client libraries.
- class AiohttpBackend¶
Bases:
AsyncBackendBackend adapter for
aiohttp.ClientSession.Requires the
aiohttppackage (pip install aiohttp). Registered foraiohttp.ClientSessionand wrapsaiohttp.ClientResponseas its response type.
- class HttpXAsyncSession¶
Bases:
AsyncBackend,CommonHttpXBackendBackend adapter for
httpx.AsyncClient.Requires the
httpxpackage (pip install httpx). Registered forhttpx.AsyncClientand used when a session is created withAsyncSession(base_url, httpx.AsyncClient).
- class HttpXSyncSession¶
Bases:
SyncBackend,CommonHttpXBackendBackend adapter for
httpx.Client.Requires the
httpxpackage (pip install httpx). Registered forhttpx.Clientand used when a session is created withSession(base_url, httpx.Client).
- class RequestsBackend¶
Bases:
SyncBackendBackend adapter for
requests.Session.Requires the
requestspackage (pip install requests). Registered forrequests.Sessionand used when a session is created withSession(base_url, requests.Session).requests.Responsehas no built-in closed state, so this backend tracks it manually via an internal_closedflag that is only ever set bysession_close().