Thanks to visit codestin.com
Credit goes to www.scribd.com

100% found this document useful (1 vote)
20 views9 pages

Pydantic Fast Review

Pydantic is a data validation and settings management library that utilizes Python type hints to enforce type safety and provide clear error messages for invalid data. It offers features such as automatic JSON schema generation, built-in validation, and seamless integration with FastAPI. Pydantic supports advanced functionalities like nested models, custom validators, and settings management from environment variables.

Uploaded by

Gabriel Mdelcye
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
20 views9 pages

Pydantic Fast Review

Pydantic is a data validation and settings management library that utilizes Python type hints to enforce type safety and provide clear error messages for invalid data. It offers features such as automatic JSON schema generation, built-in validation, and seamless integration with FastAPI. Pydantic supports advanced functionalities like nested models, custom validators, and settings management from environment variables.

Uploaded by

Gabriel Mdelcye
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Pydantic - Data Validation using Python Type

Hints

What is Pydantic?
Pydantic is a data validation and settings management library using Python type hints. It enforces type
hints at runtime and provides helpful error messages when data is invalid. Pydantic is widely used in
FastAPI and many other Python applications.

Key Features
Type Safety: Validates data using Python type hints
Fast: Core validation logic is written in Rust (Pydantic v2)
JSON Schema: Automatic JSON schema generation
IDE Support: Great editor support with auto-completion
Customizable: Extensive customization options for validation
Error Handling: Clear, detailed error messages
Serialization: Built-in serialization to dict/JSON

Installation

# Pydantic v2 (recommended)
pip install pydantic

# With email validation


pip install pydantic[email]

# Full installation
pip install pydantic[all]

Basic Usage

Simple Model

Page 1 of 9
from pydantic import BaseModel
from typing import Optional
from datetime import datetime

class User(BaseModel):
id: int
name: str
email: str
age: Optional[int] = None
created_at: datetime = datetime.now()

# Valid data
user = User(id=1, name="John Doe", email="[email protected]")
print(user)
# User(id=1, name='John Doe', email='[email protected]', age=None, created

# Invalid data raises ValidationError


try:
invalid_user = User(id="not_int", name="John") # Missing email, inva
except ValidationError as e:
print(e)

Field Validation

Built-in Validators

from pydantic import BaseModel, Field, EmailStr, validator


from typing import List

class Product(BaseModel):
name: str = Field(..., min_length=1, max_length=100)
price: float = Field(..., gt=0, description="Price must be greater th
tags: List[str] = Field(default_factory=list, max_items=5)
email: EmailStr # Requires pydantic[email]
rating: Optional[float] = Field(None, ge=0, le=5)

# Using Field for validation and metadata


class UserProfile(BaseModel):
username: str = Field(..., regex="^[a-zA-Z0-9_]+$", min_length=3)
age: int = Field(..., ge=0, le=120)
bio: Optional[str] = Field(None, max_length=500)

Page 2 of 9
Custom Validators

from pydantic import validator, root_validator

class UserAccount(BaseModel):
username: str
password: str
confirm_password: str
email: str

@validator('username')
def username_alphanumeric(cls, v):
assert v.isalnum(), 'Username must be alphanumeric'
return v

@validator('email')
def validate_email(cls, v):
if '@' not in v:
raise ValueError('Invalid email')
return v

@root_validator
def passwords_match(cls, values):
pw = values.get('password')
confirm_pw = values.get('confirm_password')
if pw is not None and confirm_pw is not None and pw != confirm_pw
raise ValueError('Passwords do not match')
return values

Advanced Features

Model Configuration

class ConfiguredModel(BaseModel):
name: str
value: int

class Config:
# Allow extra fields

Page 3 of 9
extra = "allow" # "ignore", "forbid"

# Case sensitivity
case_sensitive = False

# Validate assignments
validate_assignment = True

# Use enum values


use_enum_values = True

# JSON encoders
json_encoders = {
datetime: lambda v: v.isoformat()
}

Generic Models

from typing import TypeVar, Generic

DataT = TypeVar('DataT')

class Response(BaseModel, Generic[DataT]):


data: DataT
message: str
success: bool = True

# Usage
user_response = Response[User](
data=User(id=1, name="John", email="[email protected]"),
message="User created successfully"
)

Nested Models

class Address(BaseModel):
street: str
city: str
country: str
postal_code: str

Page 4 of 9
class Company(BaseModel):
name: str
address: Address

class Employee(BaseModel):
name: str
email: str
company: Company
addresses: List[Address] = []

# Usage
employee = Employee(
name="John Doe",
email="[email protected]",
company={
"name": "Tech Corp",
"address": {
"street": "123 Tech St",
"city": "San Francisco",
"country": "USA",
"postal_code": "94101"
}
}
)

Serialization & Deserialization

To Dict/JSON

user = User(id=1, name="John", email="[email protected]")

# To dictionary
user_dict = user.dict()
user_dict = user.dict(exclude={'created_at'})
user_dict = user.dict(include={'name', 'email'})

# To JSON
user_json = user.json()
user_json = user.json(exclude={'id'})

Page 5 of 9
From Dict/JSON

# From dictionary
user_data = {"id": 1, "name": "John", "email": "[email protected]"}
user = User(**user_data)
user = User.parse_obj(user_data)

# From JSON
json_str = '{"id": 1, "name": "John", "email": "[email protected]"}'
user = User.parse_raw(json_str)

Settings Management

from pydantic import BaseSettings

class Settings(BaseSettings):
database_url: str
secret_key: str
debug: bool = False
allowed_hosts: List[str] = ["localhost"]

class Config:
env_file = ".env"
env_file_encoding = "utf-8"

# Automatically loads from environment variables and .env file


settings = Settings()

FastAPI Integration

from fastapi import FastAPI, HTTPException


from pydantic import BaseModel, ValidationError

app = FastAPI()

class UserCreate(BaseModel):
name: str
email: str
age: Optional[int] = None

Page 6 of 9
class UserResponse(BaseModel):
id: int
name: str
email: str
age: Optional[int]

@app.post("/users/", response_model=UserResponse)
def create_user(user: UserCreate):
# Pydantic automatically validates the request body
# and converts the response to the specified model
new_user = UserResponse(
id=1,
name=user.name,
email=user.email,
age=user.age
)
return new_user

Error Handling

from pydantic import ValidationError

try:
user = User(id="invalid", name="", email="invalid-email")
except ValidationError as e:
print(e.json()) # JSON formatted errors

# Individual errors
for error in e.errors():
print(f"Field: {error['loc']}")
print(f"Error: {error['msg']}")
print(f"Type: {error['type']}")

Best Practices

1. Use Type Hints Consistently

Page 7 of 9
from typing import Optional, List, Dict, Union
from datetime import datetime

class WellTypedModel(BaseModel):
id: int
name: str
tags: List[str]
metadata: Dict[str, Union[str, int]]
created_at: Optional[datetime] = None

2. Separate Input/Output Models

class UserBase(BaseModel):
name: str
email: str

class UserCreate(UserBase):
password: str

class UserUpdate(BaseModel):
name: Optional[str] = None
email: Optional[str] = None

class UserInDB(UserBase):
id: int
hashed_password: str
created_at: datetime

class UserResponse(UserBase):
id: int
created_at: datetime

3. Use Aliases for External APIs

class ExternalAPIModel(BaseModel):
user_name: str = Field(alias="userName")
user_email: str = Field(alias="userEmail")

class Config:
allow_population_by_field_name = True # Accept both alias and fi

Page 8 of 9
Pydantic provides robust data validation, serialization, and type safety, making it an essential tool for
modern Python applications.

Page 9 of 9

You might also like