백엔드 (Backend)¶
백엔드는 ahttp_client 가 여러 서드파티 HTTP 클라이언트 라이브러리를 하나의 인터페이스로 다룰 수 있게 하는 어댑터 계층입니다. 백엔드를 직접 만들 일은 없고, 세션에 사용할 HTTP 클라이언트 클래스를 넘기면 알아서 맞는 백엔드가 선택됩니다.
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)
지원되는 백엔드¶
라이브러리 |
세션 클래스 |
백엔드 클래스 |
추가 의존성 |
|---|---|---|---|
aiohttp |
aiohttp.ClientSession |
pip install aiohttp |
|
httpx (비동기) |
httpx.AsyncClient |
pip install httpx |
|
httpx (동기) |
httpx.Client |
pip install httpx |
|
requests (동기) |
requests.Session |
pip install requests |
AsyncSession 은 aiohttp.ClientSession, httpx.AsyncClient 등 등록된 비동기 세션 클래스라면 뭐든 받습니다. Session 은 httpx.Client, requests.Session 등 등록된 동기 세션 클래스를 받습니다.
참고
aiohttp, httpx, requests 같은 선택적 의존성이 설치되어 있지 않으면 그냥 건너뜁니다. ahttp_client.backend 는 해당 서드파티 패키지를 import할 수 있는 백엔드만 골라서 내보냅니다.
백엔드 선택 방식¶
BaseBackend 는 서드파티 세션 클래스와 백엔드 클래스를 매핑하는 레지스트리를 갖고 있습니다. 구체적인 백엔드 클래스는 session_cls 와 response_cls 가 둘 다 정의되는 순간 __init_subclass__ 를 통해 알아서 자기 자신을 등록합니다.
AsyncSession(base_url, aiohttp.ClientSession) 처럼 세션을 만들면 내부적으로 AsyncBackend.from_session(aiohttp.ClientSession, base_url=base_url, **kwargs) 가 호출되어, 그 세션 클래스에 등록된 백엔드를 찾아 인스턴스화합니다. 그래서 AsyncSession/Session 에 넘기는 session=… 인자는 백엔드 인스턴스가 아니라 그냥 서드파티 클라이언트 클래스입니다.
커스텀 백엔드 작성하기¶
커스텀 HTTP 클라이언트 라이브러리를 지원하려면 비동기 클라이언트는 AsyncBackend, 동기 클라이언트는 SyncBackend 를 서브클래싱해서 session_cls/response_cls 를 정의하고, 아래 역할을 하는 추상 메소드를 구현하면 됩니다:
RequestCore를 해당 클라이언트의 요청 keyword arguments로 변환합니다 (get_request_kwargs).response_status, response_headers, response_url, response_data, response_text, response_json, response_closed 는 그 클라이언트의 응답 객체에서 상태 코드, 헤더, URL, 본문, 닫힘 상태를 읽어옵니다.
response_close 와 session_close/session_closed 는 응답과 세션 자체를 닫는 역할을 맡습니다.
내부 세션에 각 HTTP 메소드를 요청합니다 (session_request, session_get, session_post, session_options, session_delete, session_patch, session_put).
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
MyClientBackend 를 import하고 나면 AsyncSession(base_url, my_client.Session) 이 자동으로 이 백엔드에 연결됩니다. 따로 등록할 필요는 없습니다.
Reference¶
- class BaseBackend¶
지원되는 HTTP 클라이언트 라이브러리를 위한 기본 어댑터입니다.
백엔드는 클라이언트 세션을 만들고,
RequestCore값을 클라이언트별 keyword arguments로 바꾸고, 공통된 응답 인터페이스를 제공합니다.session_cls와response_cls를 둘 다 정의한 서브클래스는 자동으로 등록됩니다.- classmethod from_session(session: type[Any], **kwargs: Any) _BackendT¶
HTTP 클라이언트 세션 클래스에 등록된 백엔드를 생성합니다.
- abstractmethod get_request_kwargs(request_obj: RequestCore[Any, Any]) dict[str, Any]¶
request 디스크립터를 클라이언트별 요청 인자로 변환합니다.
- abstractmethod response_closed(response_obj: Any) bool | None¶
응답의 닫힘 상태를 반환하며, 알 수 없는 경우
None을 반환합니다.
- class AsyncBackend¶
기반 클래스:
BaseBackend,ABC비동기 HTTP 클라이언트 라이브러리를 위한 기본 어댑터 계약(contract)입니다.
- class SyncBackend¶
기반 클래스:
BaseBackend,ABC동기 HTTP 클라이언트 라이브러리를 위한 기본 어댑터 계약(contract)입니다.
- class AiohttpBackend¶
기반 클래스:
AsyncBackendaiohttp.ClientSession을 위한 백엔드 어댑터입니다.aiohttp패키지가 필요합니다 (pip install aiohttp).aiohttp.ClientSession에 등록되어 있고, 응답 타입으로aiohttp.ClientResponse를 그대로 감쌉니다.
- class HttpXAsyncSession¶
기반 클래스:
AsyncBackend,CommonHttpXBackendhttpx.AsyncClient를 위한 백엔드 어댑터입니다.httpx패키지가 필요합니다 (pip install httpx).httpx.AsyncClient에 등록되어 있으며,AsyncSession(base_url, httpx.AsyncClient)로 세션을 생성할 때 사용됩니다.
- class HttpXSyncSession¶
기반 클래스:
SyncBackend,CommonHttpXBackendhttpx.Client를 위한 백엔드 어댑터입니다.httpx패키지가 필요합니다 (pip install httpx).httpx.Client에 등록되어 있으며,Session(base_url, httpx.Client)로 세션을 생성할 때 사용됩니다.
- class RequestsBackend¶
기반 클래스:
SyncBackendrequests.Session을 위한 백엔드 어댑터입니다.requests패키지가 필요합니다 (pip install requests).requests.Session에 등록되어 있으며,Session(base_url, requests.Session)으로 세션을 생성할 때 사용됩니다.requests.Response에는 닫힘 상태가 내장되어 있지 않으므로, 이 백엔드는 오직session_close()에서만 설정되는 내부_closed플래그로 이를 직접 추적합니다.