Pydantic Validation

Вся валидация в FastAPI — это Pydantic v2. Модели описывают и вход, и выход, а фреймворк гоняет данные через них автоматически.

Базовая модель

from pydantic import BaseModel, Field

class CreateUser(BaseModel):
    name: str = Field(min_length=1, max_length=64)
    age: int = Field(ge=0, le=150)
    email: str

Невалидный запрос → 422 с подробностями по каждому полю.

Кастомный валидатор

field_validator — для одного поля, model_validator — для всей модели:

from pydantic import field_validator

class User(BaseModel):
    username: str

    @field_validator("username")
    @classmethod
    def no_spaces(cls, v: str) -> str:
        if " " in v:
            raise ValueError("username must not contain spaces")
        return v

Разделение input / output

Одна модель на вход, другая на выход — стандартный приём, чтобы не утекали секреты:

class UserIn(BaseModel):
    name: str
    password: str

class UserOut(BaseModel):
    id: int
    name: str

@app.post("/users", response_model=UserOut)
async def create(payload: UserIn):
    ...

password исчезнет из ответа.

Enum и литералы

from enum import Enum
from typing import Literal

class Role(str, Enum):
    admin = "admin"
    user = "user"

class Invite(BaseModel):
    role: Role
    notify: Literal["email", "telegram", "none"] = "none"

OpenAPI покажет только допустимые значения.

Edge-кейсы

  • Optional[T] допускает null (но не отсутствие ключа, для этого — default=None)
  • Вложенные модели валидируются рекурсивно
  • Для списка с уникальными значениями используй Annotated[list[str], Field(unique=True)]

Связанные заметки