🎯 Exemplo de Validação de Dados com Pydantic
Em poucas palavras
Vamos criar um modelo para representar um usuário, com campos como ID, nome, email, idade e um endereço.
📝 Notas e Desenvolvimento
🔗 Conexões e Contexto
- Atlas: MdC - Programação, MdC - Gestão de conhecimento pessoal
- Notas Relacionadas:
📚 Referências e Fontes
Links Externos
Citações Diretas
📂 Outros Conteúdos Preservados
Exemplo de Validação de Dados com Pydantic (Complemento)
from datetime import date
from typing import Optional, List
from pydantic import BaseModel, Field, EmailStr, ValidationError, validator
### 1. Definindo um modelo aninhado para o endereço
class Address(BaseModel):
street: str = Field(..., description="Nome da rua")
city: str = Field(..., description="Cidade")
zip_code: str = Field(..., regex=r"^\d{5}(-\d{3})?$", description="CEP no formato XXXXX ou XXXXX-XXX")
### 2. Definindo o modelo principal para o usuário
class User(BaseModel):
id: int = Field(..., gt=0, description="ID único do usuário, deve ser maior que 0")
name: str = Field(..., min_length=2, max_length=50, description="Nome completo do usuário")
email: EmailStr = Field(..., description="Endereço de e-mail válido")
age: int = Field(default=18, ge=0, le=120, description="Idade do usuário, entre 0 e 120")
is_active: bool = Field(default=True, description="Indica se o usuário está ativo")
signup_date: date = Field(default_factory=date.today, description="Data de cadastro do usuário")
tags: Optional[List[str]] = Field(None, description="Lista opcional de tags associadas ao usuário")
address: Address = Field(..., description="Endereço do usuário")
# 3. Exemplo de um validador personalizado para o nome
@validator('name')
def name_must_be_capitalized(cls, v):
if not v[0].isupper():
raise ValueError('O nome deve começar com uma letra maiúscula')
return v
class Config:
# Permite que o modelo seja instanciado com dados que não correspondem exatamente aos tipos,
# tentando fazer a coerção (ex: "123" para int)
orm_mode = True
# Gera um esquema JSON com descrições
schema_vextra = True
### --- Exemplos de Uso ---
print("--- Exemplo 1: Dados Válidos ---")
try:
user_data_valid = {
"id": 123,
"name": "Alice Smith",
"email": "[email protected]",
"age": 30,
"is_active": True,
"address": {
"street": "Rua das Flores, 100",
"city": "São Paulo",
"zip_code": "01000-000"
}
}
user1 = User(**user_data_valid)
print("Usuário válido criado com sucesso:")
print(user1.json(indent=2)) # Converte o modelo para JSON
print(f"Tipo do ID: {type(user1.id)}")
print(f"Tipo da data de cadastro: {type(user1.signup_date)}")
except ValidationError as e:
print("Erro de validação:", e.json())
print("\n--- Exemplo 2: Dados Inválidos ---")
try:
user_data_invalid = {
"id": -5, # Inválido: gt=0
"name": "bob", # Inválido: não começa com maiúscula
"email": "bob.example.com", # Inválido: não é um email válido
"age": 150, # Inválido: le=120
"address": {
"street": "Av. Principal",
"city": "Rio",
"zip_code": "123" # Inválido: regex não corresponde
}
}
user2 = User(**user_data_invalid)
print("Usuário inválido criado com sucesso:", user2)
except ValidationError as e:
print("Erro de validação (dados inválidos):")
print(e.json(indent=2))
print("\n--- Exemplo 3: Coerção de Tipos e Valores Padrão ---")
try:
user_data_coercion = {
"id": "456", # Pydantic vai converter para int
"name": "Carlos Silva",
"email": "[email protected]",
# 'age' e 'is_active' serão usados com seus valores padrão (18 e True)
"address": {
"street": "Rua da Paz, 50",
"city": "Belo Horizonte",
"zip_code": "30000-000"
}
}
user3 = User(**user_data_coercion)
print("Usuário com coerção e valores padrão:")
print(user3.json(indent=2))
print(f"ID (originalmente string): {user3.id}, Tipo: {type(user3.id)}")
print(f"Idade (valor padrão): {user3.age}")
except ValidationError as e:
print("Erro de validação:", e.json())
print("\n--- Exemplo 4: Acessando dados do modelo ---")
if 'user1' in locals():
print(f"Nome do usuário 1: {user1.name}")
print(f"Cidade do usuário 1: {user1.address.city}")
print(f"Data de cadastro do usuário 1: {user1.signup_date}")Explicação do Código:
BaseModel: A classeUser(eAddress) herda depydantic.BaseModel. Esta é a base para todos os modelos Pydantic.- Type Hints: Cada campo (
id,name,email, etc.) tem um type hint (ex:int,str,EmailStr,date,bool,Address). A Pydantic usa esses hints para validar os tipos de dados. Field: A funçãopydantic.Fieldpermite adicionar metadados e validações extras aos campos:…: Indica que o campo é obrigatório e não tem um valor padrão.gt=0,min_length=2,le=120: Restrições de valor (maior que, comprimento mínimo, menor ou igual a).regex=r"^\d{5}(-\d{3})?$": Validação de formato usando expressões regulares para o CEP.description: Uma descrição que pode ser usada para gerar documentação (ex: OpenAPI/Swagger).default=…: Define um valor padrão para o campo se ele não for fornecido.default_factory=date.today: Define uma função que será chamada para gerar um valor padrão (útil para objetos mutáveis ou datas).
EmailStr: Um tipo especial da Pydantic que valida automaticamente se a string fornecida é um endereço de e-mail válido.OptionaleList: Usados do módulotypingpara indicar quetagsé uma lista opcional de strings.- Modelos Aninhados: A classe
Addressé umBaseModelseparado e é usada como tipo para o campoaddressdentro do modeloUser, permitindo validação de estruturas de dados complexas. @validator: Decorador para criar validadores personalizados. No exemplo,name_must_be_capitalizedgarante que o nome comece com uma letra maiúscula. Se a validação falhar, ele levanta umValueError.ValidationError: Quando os dados fornecidos não correspondem às regras de validação do modelo, a Pydantic lança umaValidationError, que contém detalhes sobre quais campos falharam e por quê.- Coerção de Tipos: A Pydantic tenta converter os dados para o tipo esperado. Por exemplo, se você passar
"123"para um campoint, ela tentará convertê-lo. json(): Um método disponível nos modelos Pydantic para serializar a instância do modelo para uma string JSON.Config: A classeConfiganinhada permite configurar o comportamento do modelo, comoorm_mode = True(útil para integrar com ORMs) ouschema_extra = True(para incluir descrições no esquema JSON).
Este exemplo demonstra como a Pydantic simplifica a validação de dados, tornando seu código mais robusto e menos propenso a erros de tipo ou formato.