Pydantic Schema Standards¶
Schema Hierarchy¶
Every resource follows a four-schema pattern:
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, ConfigDict, EmailStr, Field
# Shared fields
class UserBase(BaseModel):
email: EmailStr
name: str = Field(min_length=1, max_length=200)
# Input for creation
class UserCreate(UserBase):
password: str = Field(min_length=8, max_length=128)
# Input for updates — all fields optional
class UserUpdate(BaseModel):
email: EmailStr | None = None
name: str | None = Field(None, min_length=1, max_length=200)
# Output — includes DB-generated fields, reads from ORM objects
class UserResponse(UserBase):
id: UUID
is_active: bool
created_at: datetime
model_config = ConfigDict(from_attributes=True)
Field Validators¶
Use @field_validator for single-field rules and @model_validator for cross-field rules:
from pydantic import field_validator, model_validator
class PasswordResetRequest(BaseModel):
new_password: str = Field(min_length=8)
confirm_password: str
@field_validator("new_password")
@classmethod
def password_strength(cls, v: str) -> str:
if not any(c.isupper() for c in v):
raise ValueError("Password must contain an uppercase letter")
if not any(c.isdigit() for c in v):
raise ValueError("Password must contain a digit")
return v
@model_validator(mode="after")
def passwords_match(self) -> "PasswordResetRequest":
if self.new_password != self.confirm_password:
raise ValueError("Passwords do not match")
return self
Nested Relationships¶
class OrganizationResponse(BaseModel):
id: UUID
name: str
members: list[UserResponse]
model_config = ConfigDict(from_attributes=True)
Reusable Schema Components¶
Extract shared patterns into composable pieces:
class TimestampMixin(BaseModel):
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class PaginationParams(BaseModel):
page: int = Field(1, ge=1)
size: int = Field(20, ge=1, le=100)
@property
def offset(self) -> int:
return (self.page - 1) * self.size
See Also¶
- API Documentation -- Documenting schemas in OpenAPI specs
- Route Patterns -- How schemas are used in FastAPI route definitions