Ответ
Зависимости (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) инжектируется как параметр в функцию обработчика.
Зависимости могут быть асинхронными функциями, классами, или даже другими зависимостями, формируя цепочки.
Ответ 18+ 🔞
А, ну так, слушай, смотри, блядь. Зависимости в FastAPI — это ж, ёпта, как волшебная палочка для ленивых инженеров, сука. Вместо того чтобы в каждом эндпоинте одно и то же говно копипастить, ты эту логику в одно место засунешь и потом просто подключаешь, где надо. Красота, блядь, в рот меня чих-пых!
Ну и нахуй это вообще нужно, спросишь?
- Код не повторяй, мудила! Один раз написал проверку прав — и тыкай её во все ручки, как горячие пирожки.
- Тестировать — одно удовольствие. Подменил эту зависимость в тестах — и всё, блядь, система думает, что ты Бог и царь.
- Порядок в голове и в коде. Аутентификация — отдельно, доступ к базе — отдельно, валидация — отдельно. Не превращай свой код в солянку из борща и компота, ёпта.
Смотри, как это выглядит на практике: проверка какого-нибудь ёбанного API-ключа
Представь, у тебя есть секретный ключ, и без него — ни ногой. Вот как это делается.
from fastapi import FastAPI, Depends, HTTPException, Header, status
app = FastAPI()
# 1. Вот она, наша палочка-выручалочка, функция-зависимость
def verify_api_key(api_key: str = Header(..., description="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():
"""
Сюда просто так не зайдешь. Нужен тот самый ключ.
"""
return {"message": "Доступ разрешен, проходи, не задерживайся"}
# 3. А тут мы не только пускаем, но и ключ себе забираем, чтобы посмотреть
@app.get("/items/")
async def read_items(current_api_key: str = Depends(verify_api_key)):
"""
Зависимость отработала, ключ проверила, и заодно отдала его нам в руки.
Можем, например, в логи записать, какой красавчик зашёл.
"""
return {"message": f"Доступ с ключом: {current_api_key}", "items": ["item1", "item2"]}
Суть в чём, блядь:
- Функция
verify_api_key— это и есть зависимость. Она торчит, как суровый охранник, и требуетapi_keyиз заголовка. - Ключ не подошёл? Всё, приехали.
HTTPExceptionна 403 статусе — и свободен, иди нахуй. - В первом эндпоинте (
/protected-route/) зависимость работает тихо, просто как проверка. Результат её нам не важен, главное — чтобы пропустила. - А во втором (
/items/) мы этот самый проверенный ключ ловим в параметрcurrent_api_keyи можем с ним делать что хотим.
И это, сука, только верхушка айсберга! Зависимости могут быть асинхронными, классами, и их можно вкладывать друг в друга, как матрёшек — получается овердохуища гибкости.