💻 Exemplos: Capítulo 02: Tipagem e Serialização com Pydantic v2 (BaseModel, Field)
Especialização em Backend com Python & FastAPI • Demonstrações Práticas Compiláveis
💻 Exemplo 1 — Constraints com Field e Validador de Campo Único
from pydantic import BaseModel, Field, field_validator
class ProdutoSchema(BaseModel):
id: int = Field(..., gt=0)
nome: str = Field(..., min_length=3, max_length=100)
preco: float = Field(..., gt=0.0)
tags: list[str] = Field(default_factory=list)
@field_validator("tags")
@classmethod
def validar_tags_unicas(cls, v: list[str]) -> list[str]:
if len(v) != len(set(v)):
raise ValueError("Tags não podem ser duplicadas")
return v
produto = ProdutoSchema(id=1, nome="Teclado Mecânico", preco=350.0, tags=["hardware", "usb"])
print(produto.model_dump())
# {'id': 1, 'nome': 'Teclado Mecânico', 'preco': 350.0, 'tags': ['hardware', 'usb']}
💻 Exemplo 2 — Validação Cruzada com model_validator e Serialização Customizada
from datetime import date
from pydantic import BaseModel, field_serializer, model_validator
class EventoSchema(BaseModel):
nome: str
data_inicio: date
data_fim: date
@model_validator(mode="after")
def validar_intervalo_datas(self) -> "EventoSchema":
if self.data_fim < self.data_inicio:
raise ValueError("data_fim deve ser posterior a data_inicio")
return self
class ClienteResponse(BaseModel):
nome: str
email: str
saldo: float
@field_serializer("email")
def mascarar_email(self, email: str) -> str:
usuario, dominio = email.split("@")
return f"{usuario[0]}***{usuario[-1]}@{dominio}"
@field_serializer("saldo")
def formatar_saldo(self, saldo: float) -> str:
return f"R$ {saldo:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
evento = EventoSchema(nome="Conferência Tech", data_inicio=date(2026, 9, 1), data_fim=date(2026, 9, 3))
print("Evento válido:", evento.nome)
cliente = ClienteResponse(nome="Alice", email="alice@tech.com", saldo=1250.0)
print(cliente.model_dump())
# {'nome': 'Alice', 'email': 'a***e@tech.com', 'saldo': 'R$ 1.250,00'}
💻 Exemplo 3 — Modelos Imutáveis e Estritos com ConfigDict
from pydantic import BaseModel, ConfigDict, ValidationError
class TokenPayload(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid", str_strip_whitespace=True)
sub: str
role: str
exp: int
token = TokenPayload(sub=" user_42 ", role="ADMIN", exp=1780000000)
print(token.sub) # "user_42" (espaços removidos por str_strip_whitespace)
try:
token.role = "USER" # frozen=True bloqueia reatribuição
except ValidationError as erro:
print("Bloqueado:", erro.errors()[0]["type"])
try:
TokenPayload(sub="user_1", role="ADMIN", exp=123, campo_extra="hack")
except ValidationError as erro:
print("Rejeitado por extra='forbid':", erro.errors()[0]["type"])