Как работает механизм Dependency Injection в FastAPI с помощью `Depends`?

Ответ

Механизм Dependency Injection (DI) в FastAPI позволяет объявлять зависимости, которые должны быть выполнены перед вызовом функции-обработчика эндпоинта. FastAPI автоматически разрешает эти зависимости и передает их результаты в качестве аргументов. Основным инструментом для этого является Depends.

Принцип работы:

  1. Вы объявляете функцию-зависимость (dependency function).
  2. В функции-обработчике маршрута вы указываете эту зависимость в аннотации типа аргумента, используя Depends(dependency_function).
  3. Перед тем как вызвать ваш обработчик, FastAPI вызовет функцию-зависимость.
  4. Результат, возвращенный зависимостью, будет передан в ваш обработчик в качестве значения соответствующего аргумента.

Пример: Управление сессией базы данных

Классический пример — получение сессии БД, её использование в запросе и гарантированное закрытие после завершения.

from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session

# Представим, что эти функции управляют сессией БД
from .database import SessionLocal

app = FastAPI()

# 1. Функция-зависимость
def get_db_session():
    db = SessionLocal()
    try:
        # yield передает управление и значение (сессию)
        yield db
    finally:
        # Этот код выполнится после завершения запроса
        db.close()

@app.get("/items/{item_id}")
# 2. Использование Depends для внедрения зависимости
async def read_item(item_id: int, db: Session = Depends(get_db_session)):
    # 3. FastAPI передает результат get_db_session в аргумент `db`
    item = db.query(Item).filter(Item.id == item_id).first()
    return item

Ключевые преимущества:

  • Повторное использование кода: Общую логику (аутентификация, подключение к БД) можно вынести в зависимости и использовать в разных эндпоинтах.
  • Управление ресурсами: Использование yield в зависимостях-генераторах позволяет выполнять код до и после обработки запроса (например, открытие и закрытие транзакций).
  • Упрощение тестирования: Зависимости легко подменить (mock) во время тестов, что позволяет изолировать тестируемый код.
  • Иерархия зависимостей: Зависимости могут зависеть от других зависимостей, создавая граф вычислений.

Ответ 18+ 🔞

А, ну это же про тот самый Dependency Injection в FastAPI, сука! Ну, механизм, который позволяет тебе не париться с кучей повторяющегося говна в каждом эндпоинте. Слушай, как это работает, блядь.

Вот представь: у тебя есть функция-обработчик, которая должна что-то сделать. Но перед этим ей нужно, например, проверить, кто пришёл, или достать сессию к базе данных. Так вот, вместо того чтобы в каждой функции писать один и тот же код для проверки или подключения, ты эту общую хуйню выносишь в отдельную функцию — зависимость (dependency).

А потом в своём основном обработчике ты просто говоришь: «Эй, FastAPI, перед тем как запускать мою логику, выполни-ка вот эту зависимость и передай мне её результат». И всё, блядь! FastAPI сам всё сделает, как шарманка.

Как это выглядит на практике, ёпта?

Допустим, у тебя база данных. Классика жанра, блядь.

from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session

# Представим, что эти функции управляют сессией БД
from .database import SessionLocal

app = FastAPI()

# 1. Вот она, наша зависимость-генератор, ядрёна вошь!
def get_db_session():
    db = SessionLocal()
    try:
        # yield — это магия, блядь. Отдаём сессию и замираем.
        yield db
    finally:
        # А этот кусок выполнится ПОСЛЕ того, как запрос отработает.
        # Закрываем сессию, чтоб не висела, как хуй в пальто.
        db.close()

@app.get("/items/{item_id}")
# 2. Смотри сюда, сука! Говорим: «Дай мне сессию!»
async def read_item(item_id: int, db: Session = Depends(get_db_session)):
    # 3. FastAPI уже подсунул сюда готовую сессию, пиздец как удобно!
    item = db.query(Item).filter(Item.id == item_id).first()
    return item

А в чём, собственно, профит, блядь?

  • Не повторяйся, мудак! Один раз написал логику для аутентификации или подключения к БД — используй её в сотне эндпоинтов. Умно, как мартышлюшка с калькулятором.
  • Контроль над ресурсами. Этот трюк с yield — просто волшебство. Всё, что до yield, выполнится ДО обработки запроса (например, откроем соединение). Всё, что в finally — ПОСЛЕ (закроем, почистим). Красота, блядь!
  • Тестировать — одно удовольствие. Хочешь протестировать свой эндпоинт? Просто подмени зависимость на заглушку (mock), и никакая реальная база тебе не помешает. Доверия ебать ноль к окружению, зато тесты чистые.
  • Зависимости могут зависеть от других зависимостей. Да-да, можно строить целые цепочки, как домино! Одна вызывает другую, та — третью... Пока не наступит пиздец, но если делать с умом — то очень мощно.

В общем, Dependency Injection в FastAPI — это не просто модное словечко, а реально удобная хуйня, которая экономит кучу времени и нервов. Главное — понять принцип, а дальше только успевай применять, в рот меня чих-пых!