Зависимости и доступ
Часто одни и те же действия нужны многим маршрутам: прочитать параметры страницы, проверить ключ, найти пользователя. В FastAPI для этого есть зависимости.
Depends
from fastapi import Depends, Query
def pagination(skip: int = Query(0, ge=0), limit: int = Query(10, ge=1, le=50)):
return {"skip": skip, "limit": limit}
@app.get("/todos")
def todos(page: dict = Depends(pagination)):
return TODOS[page["skip"]:page["skip"] + page["limit"]]
Перед вызовом маршрута FastAPI вызовет pagination, заполнив её параметры из запроса, и передаст результат в page. Если параметры неверные — ответ 422, как обычно. Зависимость пишется один раз и подключается к любому числу маршрутов; в /docs её параметры видны у каждого из них.
Заголовки
from fastapi import Header
def require_key(x_api_key: str | None = Header(None)):
...
Header() читает заголовок запроса. Подчёркивания в имени параметра превращаются в дефисы: x_api_key ↔ X-Api-Key. Header() без значения по умолчанию делает заголовок обязательным (без него — 422); Header(None) — необязательным, и проверку вы делаете сами.
Кто вы и можно ли вам
def current_user(x_api_key: str | None = Header(None)):
if x_api_key not in USERS:
raise HTTPException(401, "Нужен ключ доступа")
return USERS[x_api_key]
def require_admin(user: dict = Depends(current_user)):
if user["role"] != "admin":
raise HTTPException(403, "Только для админов")
return user
@app.delete("/todos/{tid}")
def delete(tid: int, admin: dict = Depends(require_admin)):
...
- 401 Unauthorized — «не знаю, кто вы»: нет ключа или он неверный;
- 403 Forbidden — «знаю, кто вы, но вам нельзя»;
- зависимости строятся друг на друге:
require_adminиспользуетcurrent_user. FastAPI вызовет их по цепочке, и каждая может прервать запрос своимHTTPException.
В настоящих проектах вместо простых ключей обычно используют токены (OAuth2, JWT): в FastAPI для этого есть OAuth2PasswordBearer из fastapi.security, и устроено всё так же — через зависимость.
Итог
Depends(функция)— вызвать функцию перед маршрутом и передать результат;- параметры зависимости (
Query,Header) заполняются из запроса; Header(None)— необязательный заголовок,x_api_key↔X-Api-Key;- 401 — кто вы, 403 — нельзя; зависимости строятся цепочкой.