fastapi-typed-errors¶
Типизированные HTTP-ошибки для FastAPI. Точные Literal-коды в OpenAPI, discriminated oneOf-union по полю code и единый источник правды — сам класс ошибки.
Зачем это нужно¶
В обычном FastAPI ошибка — это HTTPException(404, "..."). Код ошибки живёт в строке, в OpenAPI нет ни типа кода, ни модели тела ответа, а список возможных ошибок роута приходится вручную дублировать в responses={}. Клиент не может переключиться по коду, а документация быстро расходится с кодом.
fastapi-typed-errors делает ошибку классом: HTTP-статус, машинный код и модель ответа объявляются один раз и выводятся автоматически.
@app.get("/items/{item_id}")
def get_item(item_id: int):
if item_id == 0:
raise HTTPException(404, "No item") # (1)!
return {"item_id": item_id}
- Код ошибки — просто строка в
detail; в OpenAPI у 404 нет ни точного кода, ни схемы тела.
class NotFoundError(BaseError[Literal[ErrorCode.NOT_FOUND]]):
http_status = HTTPStatus.NOT_FOUND
@router.get("/items/{item_id}")
def get_item(item_id: int) -> Annotated[Item, Raises[NotFoundError]]: # (1)!
if item_id == 0:
raise NotFoundError("No item")
return Item(item_id=item_id)
- Задекларированная ошибка попадает в
responsesавтоматически: 404 с точнымLiteral["NOT_FOUND"]и телом{code, detail}.
router = with_errors(APIRouter(), auto=True) # (1)!
@router.get("/items/{item_id}")
def get_item(item_id: int) -> Item: # (2)!
if item_id == 0:
raise NotFoundError("No item")
return Item(item_id=item_id)
- Включаем авто-заполнение один раз на роутере.
- Ни одного маркера —
responsesсоберутся сами: обходчик найдётraise NotFoundError(и ошибки из зависимостей) статически. См. auto=True.
Тело ответа всегда предсказуемо:
А в OpenAPI роут получает по записи на каждый статус — с точным кодом и моделью тела. Вот как это отображается в Swagger UI:
Возможности¶
-
Единый источник правды
Статус, код и модель ответа объявляются один раз в классе ошибки. Метакласс выводит остальное.
-
Точные типы в OpenAPI
Каждый статус получает точный
Literal-код; несколько ошибок на статус — discriminatedoneOf-union поcode. -
Декларация прямо в аннотации
-> Annotated[Item, Raises[NotFoundError, ForbiddenError]]— иresponsesзаполняются сами. -
CI-проверка контрактов
check_raisesсверяет задекларированное с реально поднимаемым — в эндпоинте и его зависимостях. -
Авто-заполнение
with_errors(router, auto=True)находит ошибки статически и заполняетresponsesбез единого маркера. -
Расширяемость
Своя модель ответа-конверта, свои коды (
StrEnumили голыйLiteral), совместимость сABC.
Установка¶
Требования
- Python 3.12+ (PEP 695-дженерики)
- FastAPI ≥ 0.115 (версии
0.137–0.138исключены — см. Ограничения) - Pydantic ≥ 2.9
Дальше¶
- Быстрый старт — рабочее приложение за минуту.
- Руководство — концепции, декоратор, checker, расширение.
- Справочник API — сигнатуры из docstring-ов.