Sitemap

Pydantic and FastAPI

5 min readSep 1, 2025

Pydantic is a Python library for data validation and settings management, and it is widely used in FastAPI to validate request data and create structured models.

  • Define Python classes (models) with type hints.
  • Automatically validate and parse data.
  • Ensure type safety throughout your application.

It is similar to Python dataclasses, but with built-in validation and data parsing.

Below is an end to end example of Pydantic BaseModel and Field. Define data models using BaseModel with automatic data type validation and parsing. Use Field attributes to define metadata, default values, and validation constraints for individual fields.

GitHub code URL for reference and practice, refer item_pydantic.py file.

# BaselModel - Define data models with automatic data type validation and parsing.
# Field - It is all about metadata, default values, and validation constraints for individual fields
from pydantic import BaseModel, Field
from typing import Optional, Any, Union

class User(BaseModel):

# import Any from typing, any value
id: Any

# import Union from typing.
# Sample value - 123, '123', 123.0
customId : Union[int, str]

# ... Represents this field is required
# Only small letter characters
# name must minimum one character and maximum 10 characters
name: str = Field(..., min_length=0, max_length=10, pattern=r'^[a-z]+$')

# It is required to provide default value or None. e.g. None or 10.
city: Optional[str] = "Phoenix"

# Price is required
# value must be less than 0 and greater than or equal to 1000
price: float = Field(..., gt=0, le=1000, description="Price must be less than 0 and greater than or equal to 1000")

# active is boolean as True or False
# Default value is True.
active: bool = Field(default_value = True)

# age value must be less than 0 and greater than or equal to 100.
age: int = Field(gt=0, le=100, description="Price must be less than 0 and greater than or equal to 100")

# list of str hobbies=['reading', 'cooking', 'running']
hobbies : list[str]

# Dictionary, sample={'abc': 1}
sample : dict[str, int]

user = User(id=123, customId=123.0, name="david", price=900, active=True, age=25, hobbies=['reading', 'cooking', 'running'], sample = {"abc" : 1, "def" : 2})

print(user)
print(user.name)

OUTPUT:

Run Command: py item_pydantic.py

Press enter or click to view image in full size

Constraint Types

Pydantic allow us to provide different types of constraint based of data type as shown below:

GitHub code URL for reference and practice, refer item_pydantic_con.py file.

# An int with a value greater than 0 and less than or eqqual to 100
conint → conint(gt=0, le=100)

# float with a value greater than 0.0 and less than 10.0
confloat → confloat(gt=0.0, lt=10.0)

# string with a minimum lenght 3, maximum length 10, and regex having alphabetical characters only.
constr → constr(min_length=3, max_length=10, regex='^[a-z]+$')

# list with a minimum 1 item and maximum 5 items.
conlist → conlist(int, min_items=1, max_items=5)

Example:

from pydantic import BaseModel, conint, constr

class User(BaseModel):

# minimum lenght 3, maximum length 10, and regex having alphabetical characters only.
name: constr(min_length=0, max_length=10, pattern=r'^[a-zA-Z]+$')

# value greater than 0 and less than or eqqual to 100
price: conint(gt=0, le=100)

user = User(price=50, name="David")

print(user)

OUTPUT:

Press enter or click to view image in full size

Custom Field Validation

field_validator helps us to define custom field specific validations.

GitHub code URL for reference and practice, refer item_pydantic_custom_field_validation.py file.

from pydantic import BaseModel, field_validator

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

# field validatoe on 'email' field.
# It will throw error if email id not having @.
@field_validator("email")
def validate_email_id(cls, v):
if "@" not in v:
raise ValueError("Invalid email address")
return v

# field validatoe on 'name' field.
# It will throw error if name is NOT david.
@field_validator("name")
def validate_name(cls, v):
if v != "david":
raise ValueError("Name id NOT david")
return v

user = User(name = "david", email = "test@test.com")
print(user)

OUTPUT (Success Scenario):

Press enter or click to view image in full size

OUTPUT (Fail Scenario):

Update the email ID test@test.com to testest.com by removing the @ symbol.

user = User(name = "david", email = "testtest.com")

Check the output after running the code, as it will produce the output shown below.

Press enter or click to view image in full size

Pydantic with FastAPI

Below is an example to use Pydantic with FastAPI to map JSON with Person model class.

Create Person class inheriting from BaseModel and has two fields: name (a string, defaulting to None) and age (an integer, defaulting to 0). A single POST endpoint /person is defined, which expects a request body matching the Person model. When a request is sent to /person, FastAPI automatically parses and validates the incoming JSON data against the Person model, making sure the input types are correct.

Inside the function getMessage, the person object (an instance of Person) is printed to the console, and then the API responds with a JSON object containing the received name and age under the keys “return_name” and “return_age”.

Essentially, this example demonstrates how FastAPI and Pydantic work together to handle structured request data and return a validated response.

Follow link to read more about FastAPI in detail.

GitHub code URL for reference and practice below inline code, refer item_pydantic_fastapi.py file.

from fastapi import FastAPI
from pydantic import BaseModel

# Person class Pydanitc BaseModel
class Person(BaseModel):
name: str = None
age: int = 0

app = FastAPI()

# Collect name and age using Person class.
@app.post("/person")
async def getMessage(person: Person):
print(person)
return {"return_age": person.age, "return_name" : person.name}

Start Server:

Use command to start server: uvicorn item_pydantic_fastapi:app — reload

OUTPUT:

Press enter or click to view image in full size

I hope you found out this article interesting and informative. Please share it with your friends to spread the knowledge.

You can follow me for upcoming blogs follow.
Thank you!

--

--

No responses yet