← Назад к списку
ТехническаяPythonMiddle

Как устроено внедрение зависимостей в FastAPI и какую роль играет Pydantic?

Короткий ответ

  • Depends объявляет зависимость параметром эндпоинта
  • FastAPI сам строит и кэширует граф зависимостей на запрос
  • Зависимость-генератор с yield освобождает ресурсы (сессия БД)
  • Pydantic валидирует вход по аннотациям и сериализует ответ
  • Из типов автоматически строится OpenAPI-документация
  • В тестах зависимости подменяются через dependency_overrides

FastAPI через Depends собирает зависимости по аннотациям и кэширует их в рамках запроса, а Pydantic превращает типы в валидацию, сериализацию и OpenAPI-схему.

Как сказать вслух

пример ответа

В FastAPI зависимости объявляются прямо в сигнатуре эндпоинта через Depends: нужна сессия базы или текущий пользователь — просто указываю параметр, и фреймворк сам его создаст и передаст. Зависимости могут зависеть друг от друга, в рамках одного запроса результат кэшируется, а вариант с yield работает как контекстный менеджер — удобно закрывать сессию. Pydantic при этом валидирует входные данные по аннотациям и генерирует документацию. В тестах всё это легко подменяется.

Подробный ответ

Основной ответ

FastAPI читает сигнатуру эндпоинта: path- и query-параметры берёт из простых типов, тело — из моделей Pydantic, а параметры с Depends(func) разрешает, вызывая функцию-зависимость. Зависимости образуют граф (могут иметь свои Depends), результат по умолчанию кэшируется в рамках запроса. Зависимость-генератор с yield выполняет код после yield по завершении запроса — стандартный способ выдать и закрыть сессию БД. Pydantic v2 валидирует и приводит типы входных данных, возвращая 422 с понятными ошибками, сериализует ответ по response_model и поставляет JSON Schema для автодокументации /docs. Для тестов app.dependency_overrides позволяет подменить любую зависимость заглушкой без патчинга.

Ключевые моменты

  • Граф зависимостей. Зависимости вкладываются друг в друга: get_current_user зависит от get_db и токена; FastAPI разрешает цепочку сам.
  • yield-зависимости. Код до yield — на входе, после — на выходе; так управляют сессиями, транзакциями и внешними клиентами.
  • Pydantic v2. Валидация на ядре на Rust, строгие и гибкие режимы, model_validate/model_dump; ошибки клиенту — структурированный 422.
  • Тестируемость. dependency_overrides подменяет БД или авторизацию в TestClient — юнит-тесты без реальной инфраструктуры.

Практический контекст

На собеседовании по FastAPI это центральная тема: просят объяснить, как отдать сессию БД в эндпоинт, как сделать проверку прав или как подменить зависимость в тесте. Интервьюер смотрит, понимает ли кандидат, что DI здесь декларативный и завязан на аннотации, и отличает ли async- и sync-зависимости (sync уходят в пул потоков).

Пример кода

from fastapi import FastAPI, Depends
from pydantic import BaseModel

app = FastAPI()

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

class UserIn(BaseModel):
    email: str
    age: int

@app.post("/users")
def create_user(user: UserIn, db=Depends(get_db)):
    return {"email": user.email}

Частые ошибки

  • Создают сессию БД глобально вместо yield-зависимости и ловят утечки соединений
  • Пишут def-эндпоинты с блокирующим кодом внутри async def, блокируя событийный цикл
  • Патчат модули в тестах вместо штатного dependency_overrides

ИП Кочкин Алексей Сергеевич · ИНН 390509026279 · ОГРНИП 325390000030973 · jiniys2005@yandex.ru