Как реализовать зависимости (Dependencies) в FastAPI? Приведите пример.

«Как реализовать зависимости (Dependencies) в FastAPI? Приведите пример.» — вопрос из категории Библиотеки и модули, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Зависимости (Dependencies) в FastAPI — это мощный механизм для инъекции общей логики в обработчики маршрутов. Они позволяют переиспользовать код, упрощать тестирование и структурировать приложение, например, для аутентификации, авторизации, валидации данных или работы с базой данных.

Почему это важно:

  • Переиспользование кода: Избегайте дублирования логики в разных эндпоинтах.
  • Тестируемость: Зависимости легко мокать при тестировании.
  • Структурирование: Четкое разделение ответственности.

Пример: Зависимость для проверки API-ключа

Рассмотрим зависимость, которая проверяет наличие и корректность API-ключа, переданного в заголовке запроса.

from fastapi import FastAPI, Depends, HTTPException, Header, status

app = FastAPI()

# 1. Определение функции-зависимости
def verify_api_key(api_key: str = Header(..., description="API-ключ для доступа")):
    """
    Проверяет API-ключ, переданный в заголовке 'api-key'.
    """
    if api_key != "super-secret-key": # Используйте более надежный способ хранения ключа в реальных проектах
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Неверный API-ключ"
        )
    return api_key

# 2. Использование зависимости в маршруте
@app.get("/protected-route/", dependencies=[Depends(verify_api_key)])
async def protected_route():
    """
    Эндпоинт, доступный только при наличии валидного API-ключа.
    """
    return {"message": "Доступ разрешен"}

# 3. Использование зависимости для получения значения
@app.get("/items/")
async def read_items(current_api_key: str = Depends(verify_api_key)):
    """
    Эндпоинт, который использует API-ключ, возвращенный зависимостью.
    """
    return {"message": f"Доступ с ключом: {current_api_key}", "items": ["item1", "item2"]}

В этом примере:

  • Функция verify_api_key определена как зависимость. Она ожидает api_key из заголовка api-key.
  • Если ключ неверный, генерируется HTTPException со статусом 403 Forbidden.
  • В первом маршруте (/protected-route/) зависимость используется только для проверки доступа (dependencies=[Depends(verify_api_key)]).
  • Во втором маршруте (/items/) зависимость также проверяет доступ, но её возвращаемое значение (current_api_key) инжектируется как параметр в функцию обработчика.

Зависимости могут быть асинхронными функциями, классами, или даже другими зависимостями, формируя цепочки.