Как устроено внедрение зависимостей в FastAPI?
- Что делает Depends в FastAPI?
- Как в FastAPI получить сессию БД на запрос?
Depends(func) — FastAPI вызывает func перед обработчиком и передаёт результат в параметр. Зависимости образуют граф, результат кэшируется в пределах запроса, зависимость с yield выполняет очистку после ответа (сессия БД, транзакция). В тестах их подменяют через app.dependency_overrides.
- Параметры зависимости сами берутся из запроса: заголовки, query, тело
- Зависимость на роутер или приложение — для авторизации на группу маршрутов
- Annotated[Session, Depends(get_session)] — переиспользуемый тип
А ещё Похоже на фикстуры pytest: та же идея внедрения по объявлению
Подробно
Как работает. При старте FastAPI анализирует сигнатуры обработчиков и зависимостей и строит граф. На каждый запрос он вычисляет зависимости, извлекая их собственные параметры из запроса, и передаёт результаты дальше. Одна и та же зависимость в графе вычисляется один раз за запрос (use_cache=True).
yield-зависимости — как контекстный менеджер: код до yield — перед обработчиком, после — после ответа. Удобно для сессий и транзакций.
Тесты:
app.dependency_overrides[get_session] = lambda: test_session
Отличие от Spring: нет контейнера с синглтонами и сканированием — зависимости это функции, жизненный цикл по умолчанию — запрос. Долгоживущие объекты (пул соединений, клиенты) создают в lifespan приложения.
Пример
from typing import Annotated
from fastapi import Depends, FastAPI
def get_session():
session = SessionLocal()
try:
yield session
finally:
session.close()
SessionDep = Annotated[Session, Depends(get_session)]
def current_user(token: str = Header(), session: SessionDep = ...):
return auth(session, token)
@app.get("/orders")
def orders(user: Annotated[User, Depends(current_user)], session: SessionDep):
return session.query(Order).filter_by(owner=user.id).all()Что хотят услышать
- Механика Depends и граф.
- Кэш в пределах запроса и yield для очистки.
- Подмена в тестах.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓Depends вызывает функцию перед обработчиком; yield — очистка после ответа
- ✗Зависимость вызывается один раз при старте приложения и кэшируется
- ✗Подменить зависимость в тестах нельзя, только моками модулей
- ✗Depends работает только с асинхронными функциями
Разбор темы
- Веб на Python — WSGI и ASGI, FastAPI, HTTP-клиенты, JSON, Django ORM
Чем WSGI отличается от ASGI, простой API на FastAPI и внедрение зависимостей, requests и httpx с таймаутами, JSON с датами и деньгами, N+1 в Django.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.