Retejo#
Retejo (ретейо) — современная библиотека для декларативного описания web-клиентов с поддержкой валидации и полной типизацией
Возможности#
- Валидация данных через
adaptix
илиpydantic
. - Полная типизация для раннего обнаружения ошибок.
- Поддержка HTTP-клиентов:
requests
,aiohttp
,httpx
. - Декларативное описание методов.
Установка#
Концепции#
1. Декларативное описание методов.#
Каждый метод описывается как независимый класс, наследуюясь от базового класса Method и передавая тип ответ в Generic параметр Method
class GetUser(Method[User]):
__url__ = "users/{id}"
__method__ = "GET"
id: UrlVar[int]
details: QueryParam[bool]
access_token: Header[str]
2. Независимость от web клиента.#
Любой метод можно переиспользовать с любым клиентом, ведь метод не привязан к ним
Базовое использование#
1. Описание моделей#
2. Описание API-методов#
class GetPost(Method[Post]):
__url__ = "posts/{id}"
__method__ = "GET"
id: UrlVar[int] # Параметр URL
class CreatePost(Method[PostId]):
__url__ = "posts"
__method__ = "POST"
user_id: Body[int]
title: Body[str]
body: Body[str]
3. Создание клиента и переопределене логики парсинга ответа#
class JSONPlaceholderClient(RequestsAdaptixClient):
def __init__(self):
super().__init__("https://jsonplaceholder.typicode.com/")
def init_response_factory(self) -> Retort:
return super().init_response_factory().extend(
recipe=[
# camelCase -> lower_case
name_mapping(name_style=NameStyle.CAMEL)
]
)
get_post = bind_method(GetPost)
create_post = bind_method(CreatePost)
class JSONPlaceholderClient(AiohttpAdaptixClient):
def __init__(self):
super().__init__("https://jsonplaceholder.typicode.com/")
def init_response_factory(self) -> Retort:
return super().init_response_factory().extend(
recipe=[
# camelCase -> lower_case
name_mapping(name_style=NameStyle.CAMEL)
]
)
get_post = bind_method(GetPost)
create_post = bind_method(CreatePost)
class JSONPlaceholderClient(HttpxAdaptixSyncClient):
def __init__(self):
super().__init__("https://jsonplaceholder.typicode.com/")
def init_response_factory(self) -> Retort:
return super().init_response_factory().extend(
recipe=[
# camelCase -> lower_case
name_mapping(name_style=NameStyle.CAMEL)
]
)
get_post = bind_method(GetPost)
create_post = bind_method(CreatePost)
class JSONPlaceholderClient(HttpxAdaptixAsyncClient):
def __init__(self):
super().__init__("https://jsonplaceholder.typicode.com/")
def init_response_factory(self) -> Retort:
return super().init_response_factory().extend(
recipe=[
# camelCase -> lower_case
name_mapping(name_style=NameStyle.CAMEL)
]
)
get_post = bind_method(GetPost)
create_post = bind_method(CreatePost)
Tip
Возможно, вы подумаете, что использование bind_method
ломает типизиацию, но это не так.
Полностью экваивалентно
4. Использование клиента#
Маркеры параметров#
С помощью маркеров помечают куда нужно сопоставить данные параметра при отправке запроса
Retejo предоставляет 6 видов маркеров
Маркер | Назначение | Пример |
---|---|---|
Body |
Тело запроса (application/json) | title: Body[str] |
File |
Файл (multipart/form-data) | avatar: File |
Header |
Заголовок запроса | auth: Header[str] |
QueryParam |
Параметр URL (?key=value) | page: QueryParam[int] |
UrlVar |
Переменная пути URL (/end/{param}) | id: UrlVar[int] |
Omittable |
Параметр опускается, если значение является Omitted() | opt: Body[Omittable[str]] = Omitted() |
Кастомная обработка маркеров#
Обработку каждого маркера можно с легкостью переопределить.
Давайте добавим пару рецептов для фабрики HeaderMarker. Опишем, что при отправке запроса:
- Должен добавиться тип токена
Bearer
. - Должно поменяться имя хедера с access_token на Authorization
class AddModel(Method[Any]):
__url__ = "user/{user_id}/models"
__method__ = "POST"
user_id: UrlVar[int]
model_name: Body[str]
access_token: Header[str]
description: Body[Omittable[str]] = Omitted()
class CustomClient(RequestsAdaptixClient):
def init_markers_factories(self) -> MarkersFactories[Retort]:
factories = super().init_markers_factories()
factories[HeaderMarker].extend(
recipe=[
dumper(
lambda x: f"Bearer {x}", # Преобразование значения
P[AddModel].access_token
),
name_mapping(
AddModel,
map={"access_token": "Authorization"} # Имя заголовка
)
]
)
return factories
Интеграции#
Поддерживаемые HTTP-клиенты#
requests
- синхронныйaiohttp
- асинхронныйhttpx
- синхронный/асинхронный
Поддерживаемые валидаторы#
adaptix
(рекомендуется)pydantic (v2)
Преимущества использования#
- Декларативный подход - чёткое разделение описания методов и клиента.
- Автоматическая валидация - данных запроса и ответа.
- Полная типизация - позволяет обнаружить ошибки до запуска кода.
- Гибкая конфигурация - кастомизация всех аспектов запроса.
- Единый стиль - для синхронного и асинхронного кода.