Introduction¶
ahttp-client 는 Annotated Type 과 @decorator 를 활용해서 비동기(그리고 동기) HTTP 요청을 간결하고 직관적으로 작성할 수 있게 해주는 파이썬 패키지입니다.
주요 특징
request 또는 get, post, put, patch, delete, options 데코레이터로 HTTP 엔드포인트를 선언합니다.
Annotated Type으로 경로, 쿼리, 헤더, 본문 등 HTTP 구성요소를 관리합니다 (HTTP 구성요소(Component) 참고).
HTTP 요청 전후로 요청 처리 과정을 커스터마이징할 수 있고, 지수 백오프 방식의 재시도 기능도 선택적으로 쓸 수 있습니다 (Hooking 기능, 재시도 (Retry) 참고).
서비스를 선언하는 방식을 바꾸지 않고도 aiohttp, httpx, requests 를 교체 가능한 백엔드로 바꿔 쓸 수 있습니다 (백엔드 (Backend) 참고).
dataclasses, pydantic, marshmallow 용으로 등록된 코덱을 이용해 타입이 지정된 요청 모델을 직렬화하고 응답을 역직렬화합니다 (직렬화 (Serialization) 참고).
4xx/5xx 응답에 대해 타입이 지정된 HTTPException 을 발생시킵니다 (예외 (Exception) 참고).
설치¶
ahttp-client 는 Python 3.11 이상이 필요합니다. 서비스에서 사용할 HTTP 클라이언트 라이브러리에 맞는 추가 의존성(extra)을 설치하세요.
pip install "ahttp-client[aiohttp]"
pip install "ahttp-client[httpx]"
pip install "ahttp-client[requests]"
pydantic.BaseModel 인스턴스를 직렬화·역직렬화하려면 pydantic extra를 추가하세요 (직렬화 (Serialization) 참고).
pip install "ahttp-client[aiohttp,pydantic]"
시작하기¶
두 세션 기반 클래스가 두 스타일의 클라이언트를 각각 담당합니다:
스타일 |
지원하는 클라이언트 클래스 |
세션 클래스 |
|---|---|---|
비동기 |
aiohttp.ClientSession, httpx.AsyncClient |
AsyncSession |
동기 |
requests.Session, httpx.Client |
Session |
비동기 클라이언트¶
ahttp_client.AsyncSession 을 상속한 GithubService 클래스를 만들고, request 데코레이터로 list_repositories 메소드를 정의합니다.
user 인수는 Annotated Type을 통해 HTTP 구성요소(Path)를 정의합니다.
class GithubService(AsyncSession):
def __init__(self):
super().__init__("https://api.github.com", aiohttp.ClientSession)
@request("GET", "/users/{user}/repos")
async def list_repositories(
self, response: Response, user: Annotated[str, Path]
) -> list[dict[str, Any]]:
return response.json()
비동기 컨텍스트 매니저(async with)로 GithubService 객체를 생성합니다.
async with GithubService() as service:
result = await service.list_repositories(user="gunyu1019")
print(result)
GithubService 내부의 클라이언트 세션은 비동기 컨텍스트 매니저를 벗어나는 순간 자동으로 종료됩니다.
동기 클라이언트¶
동기 방식 서비스는 대신 Session 을 상속하고, requests.Session 이나 httpx.Client 와 함께 일반 함수를 사용합니다.
class GithubService(Session):
def __init__(self):
super().__init__("https://api.github.com", requests.Session)
@request("GET", "/users/{user}/repos")
def list_repositories(
self, response: Response, user: Annotated[str, Path]
) -> list[dict[str, Any]]:
return response.json()
with GithubService() as service:
result = service.list_repositories(user="gunyu1019")
print(result)
GithubService 내부의 클라이언트 세션은 with 블록을 벗어나는 순간 자동으로 종료됩니다.