Привет! FastAPI предоставляет мощный механизм внедрения зависимостей через Depends. Это позволяет разделять логику, переиспользовать код и делать приложение чище.
В этой статье мы разберём:
- Что такое зависимости
- Базовое использование
Depends - Внедрение зависимостей
- Глобальные и эндпоинт-зависимости
- Практические примеры (БД, аутентификация)
- Что нужно знать перед началом
- Основная часть
- Что такое зависимости
- Базовое использование
- Зависимости с параметрами
- Вложенные зависимости
- Глобальные зависимости
- Пример с аутентификацией
- Пример с базой данных
- Полный пример
- Задачи для закрепления
- Нюансы и подводные камни
- Частые ошибки и как их избежать
- Ошибка 1: Забыл импортировать Depends
- Ошибка 2: Неправильное использование Depends
- Ошибка 3: Глобальные зависимости без Depends
- Шпаргалка
- Заключение
- КВИЗ
- Что дальше?
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный FastAPI
- Базовое понимание функций и классов
Совет: Зависимости помогают избежать дублирования кода и упрощают тестирование.
Основная часть
Что такое зависимости
Зависимости — это механизм, который позволяет внедрять общую логику в эндпоинты.
Пример без зависимости:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/")
def get_users(q: str = None, page: int = 1, limit: int = 10):
# Много повторяющегося кода
return {"query": q, "page": page, "limit": limit}
@app.get("/items/")
def get_items(q: str = None, page: int = 1, limit: int = 10):
# Тот же код
return {"query": q, "page": page, "limit": limit}С зависимостью:
from fastapi import FastAPI, Depends
app = FastAPI()
def common_parameters(q: str = None, page: int = 1, limit: int = 10):
return {"q": q, "page": page, "limit": limit}
@app.get("/users/")
def get_users(params: dict = Depends(common_parameters)):
return {"users": [], **params}
@app.get("/items/")
def get_items(params: dict = Depends(common_parameters)):
return {"items": [], **params}Совет: Зависимости позволяют вынести общую логику в отдельные функции.
Базовое использование
from fastapi import FastAPI, Depends
app = FastAPI()
def get_token():
return "secret-token"
@app.get("/secure/")
def secure_endpoint(token: str = Depends(get_token)):
return {"token": token}Совет:
Dependsвызывается при каждом запросе.
Зависимости с параметрами
def get_user_by_id(user_id: int):
return {"id": user_id, "name": f"Пользователь {user_id}"}
@app.get("/users/{user_id}")
def get_user(user_data: dict = Depends(get_user_by_id)):
return user_dataВложенные зависимости
def get_db_connection():
return {"host": "localhost", "database": "test"}
def get_user_repository(db: dict = Depends(get_db_connection)):
return {"users": [{"id": 1, "name": "Анна"}], "db": db}
@app.get("/users/")
def get_users(repo: dict = Depends(get_user_repository)):
return repoГлобальные зависимости
from fastapi import FastAPI, Depends
app = FastAPI(dependencies=[Depends(verify_token)])
def verify_token():
return {"verified": True}
@app.get("/protected/")
def protected_endpoint():
return {"message": "Доступ разрешён"}Пример с аутентификацией
from fastapi import FastAPI, Depends, HTTPException, status
app = FastAPI()
users_db = {
"admin": {"password": "secret", "role": "admin"},
"user": {"password": "123", "role": "user"}
}
def get_current_user(username: str, password: str):
if username not in users_db:
raise HTTPException(status_code=401, detail="Пользователь не найден")
if users_db[username]["password"] != password:
raise HTTPException(status_code=401, detail="Неверный пароль")
return {"username": username, "role": users_db[username]["role"]}
@app.post("/login")
def login(username: str, password: str):
user = get_current_user(username, password)
return {"message": "Успешный вход", "user": user}
@app.get("/admin/")
def admin_endpoint(user: dict = Depends(get_current_user)):
if user["role"] != "admin":
raise HTTPException(status_code=403, detail="Недостаточно прав")
return {"message": "Добро пожаловать, администратор!"}Пример с базой данных
from fastapi import FastAPI, Depends
app = FastAPI()
def get_db():
return {"connection": "DB connected"}
def get_user_service(db: dict = Depends(get_db)):
return {"users": [{"id": 1, "name": "Анна"}], "db": db}
@app.get("/users/")
def get_users(service: dict = Depends(get_user_service)):
return serviceПолный пример
from fastapi import FastAPI, Depends, HTTPException, status
app = FastAPI()
# Зависимости для БД
def get_db():
return {"db": "connected", "data": [{"id": 1, "name": "Анна"}]}
# Зависимость для аутентификации
def verify_token(authorization: str = None):
if not authorization or not authorization.startswith("Bearer "):
raise HTTPException(status_code=401, detail="Токен не предоставлен")
token = authorization.split(" ")[1]
if token != "secret":
raise HTTPException(status_code=401, detail="Неверный токен")
return {"user": "admin"}
# Зависимость для пагинации
def common_parameters(q: str = None, page: int = 1, limit: int = 10):
return {"q": q, "page": page, "limit": limit}
@app.get("/public/")
def public_endpoint():
return {"message": "Публичный эндпоинт"}
@app.get("/private/")
def private_endpoint(auth: dict = Depends(verify_token)):
return {"message": "Приватный эндпоинт", "user": auth}
@app.get("/users/")
def get_users(
db: dict = Depends(get_db),
params: dict = Depends(common_parameters)
):
return {"db": db, **params}
@app.get("/items/")
def get_items(
db: dict = Depends(get_db),
params: dict = Depends(common_parameters)
):
return {"items": [], "db": db, **params}Задачи для закрепления
Задача 1. Создай зависимость для аутентификации.
Задача 2. Создай зависимость для подключения к БД.
Задача 3. Используй зависимости в эндпоинте.
Задача 4. Создай вложенную зависимость.
Задача 5. Создай глобальную зависимость.
Ответы:
Задача 1.
def verify_token(token: str):
if token != "secret":
raise HTTPException(status_code=401)
return {"user": "admin"}Задача 2.
def get_db():
return {"db": "connected"}Задача 3.
@app.get("/users/")
def get_users(db: dict = Depends(get_db)):
return dbЗадача 4.
def get_user_repo(db: dict = Depends(get_db)):
return {"users": [], "db": db}Задача 5.
app = FastAPI(dependencies=[Depends(verify_token)])Нюансы и подводные камни
Dependsвнедряет зависимости в эндпоинты.- Зависимости могут быть вложенными.
- Глобальные зависимости применяются ко всем эндпоинтам.
- Зависимости вызываются при каждом запросе.
- Можно использовать
Dependsс параметрами. - Зависимости упрощают тестирование и переиспользование кода.
Dependsработает с асинхронными функциями.
Частые ошибки и как их избежать
Ошибка 1: Забыл импортировать Depends
from fastapi import Depends
Ошибка 2: Неправильное использование Depends
item: dict = Depends(func)
Ошибка 3: Глобальные зависимости без Depends
app = FastAPI(dependencies=[Depends(func)])
Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Базовая зависимость | def func(): return ... |
| Внедрение зависимости | item: dict = Depends(func) |
| Глобальная зависимость | app = FastAPI(dependencies=[Depends(func)]) |
| Вложенная зависимость | def nested(db: dict = Depends(get_db)): |
Заключение
Сегодня мы:
- Изучили механизм Depends
- Создавали зависимости для общих задач
- Использовали вложенные и глобальные зависимости
- Применяли для аутентификации и БД








