Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
In modern Python development, handling and validating data efficiently is crucial, especially when working with APIs, configurations, or user inputs. Pydantic is a powerful library designed to simplify this process by providing easy-to-use tools for data parsing and validation using Python type hints. Unlike traditional approaches, Pydantic automatically enforces type checks and constraints at runtime, helping developers catch errors early and write more reliable code. Whether you’re working on a small script or a complex application, mastering Pydantic can save you time and improve the robustness of your data handling.
Pydantic is written in Rust under the hood — it’s not just elegant, it’s blazing fast.
Normal Class
A normal Python class is the most fundamental way to define a structure for your data. You manually create an __init__
method to initialize attributes and handle assignments yourself. While it gives full control, it also means writing more boilerplate code and handling things like string representation or equality checks manually. There’s no built-in type enforcement, so if you accidentally pass incorrect data types, Python won’t raise an error unless you explicitly check for it in your code.
class Employee:
def __init__(self, name, age):
self.name = name
self.age = age
Emp = Employee("Alice", 25)
❌ No type checking, no default serialization, and if someone passes age="twenty five" - no errors!
@dataclass
The @dataclass
decorator,simplifies class definitions by automatically generating methods like __init__
, __repr__
, __eq__
, and more based on class attributes. It makes code cleaner and easier to maintain, especially when dealing with data-focused classes. Although you can annotate attributes with type hints, @dataclass
does not enforce type checking at runtime — the hints are mainly for documentation and static analysis tools. It’s a great choice when you want less boilerplate but don’t need full validation.
from dataclasses import dataclass
@dataclass
class Employee:
name: str
age: int
Emp = Employee("John",30)
❌ No automatic type validation
Basemodel
Pydantic’s BaseModel
takes data classes to the next level by adding powerful runtime validation and parsing capabilities. By simply inheriting from BaseModel
, your class not only benefits from auto-generated methods but also gains strict type enforcement. If invalid data is passed, Pydantic raises informative validation errors, helping catch bugs early. Additionally, it supports easy conversion between data formats (like dicts and JSON), making it especially useful in web development, APIs, and data processing pipelines. From version 2 onward, Pydantic is backed by a Rust core, giving it excellent performance.
from pydantic import BaseModel
class Person1(BaseModel):
name:str
age:int
city:str
person=Person1(name="George",age=30,city="Bangalore")
print(person)
✅ Clean
✅ Type-safe (throws error if age="thirty"
)
Smart agents need smart data — Pydantic’s BaseModel ensures your AI works with clean, validated inputs every time.
🔍 Let’s Dive into the Basics of Pydantic’s Basemodel
Before we explore advanced use cases, it’s essential to understand how BaseModel
works at its core. Pydantic’s BaseModel
allows you to define data structures using standard Python classes with type annotations — but with superpowers. The moment you inherit from BaseModel
, Pydantic takes over validation, parsing, and serialization automatically. It checks your data at runtime, ensuring the right types and formats are passed into your model. This means fewer bugs, cleaner code, and more confidence when building applications — especially in fast-moving areas like AI agents, APIs, or data pipelines.
Optional
in PydanticIn Pydantic, Optional
is used to define fields that are not strictly required — meaning the field can either hold a value or be completely absent (or None
). It’s based on Python’s typing.Optional
, which is just a shorthand for saying a value can be of a certain type or None
. For example, Optional[str]
means the field can be a string or None
. In Pydantic, if you mark a field as optional without a default value, it’s still considered required unless you provide a default (like None
). So to make a field truly optional, you typically combine Optional
with a default: email: Optional[str] = None
. This makes the field skip validation if the value is not provided — ideal for optional inputs in forms, APIs, or AI agent parameters.
from typing import Optional
from pydantic import BaseModel
class Employee(BaseModel):
id: int
name: str
department: str
salary: Optional[float] = None # Optional with default value
is_active: Optional[bool] = True # Optional with default value
In this example, we’re defining an Employee
model using Pydantic’s BaseModel
. Here’s what each part means:
id
, name
, and department
are required fields. If any of these are missing when creating an Employee
, Pydantic will raise a validation error.salary
is an optional field, meaning it can be either a float
or None
. We’ve set its default to None
, so it’s perfectly valid to skip it during model creation.is_active
is also an optional field with a default value of True
. If it’s not provided, the model assumes the employee is active by default.⚠️ What Happens If Required Fields Are Missing?
Let’s try creating an employee instance without providing a required field:
emp = Employee(id=101, name="Alice")
This will raise an error:
pydantic.error_wrappers.ValidationError:
3 validation errors for Employee
department
field required (type=value_error.missing)
Pydantic clearly informs us that the department
field is missing. Optional fields like salary
and is_active
are ignored if not supplied, thanks to their default values.
When you need to work with multiple values of the same type—like a list of skills, tags, or items—Pydantic makes it simple with Python’s standard List
type hint from the typing
module. Defining a list in a BaseModel
ensures each element in the list matches the specified type, and the entire structure is validated automatically.
For example:
from typing import List
from pydantic import BaseModel
from typing import List
class Classroom(BaseModel):
room_number:int
students: List[str] #List of strings
capacity:int
In this model, students must be a list where every item is a string. Pydantic will raise a validation error if you try to create an Classroom with a non-list value or if any element inside the list is not a string.
⚠️ Common Error with Lists
If you create an instance like this:
cls= Classroom(room_number = 1, students ="Alice, John", capacity = 20 )
You’ll get a validation error because students expects a list, but you passed a single string:
To fix this, always pass a list — even if it contains just one element:
cls= Classroom(room_number = 1, students = ["Alice, John"], capacity = 20 )
Using lists in your models helps keep your data structured, clean, and ready for operations like filtering, searching, or processing—perfect for APIs, AI agents, and more.
Field()
in PydanticPydantic gives you fine-grained control over your data using the Field()
function. You can define extra rules for each field like minimum or maximum length for strings, or value ranges for numbers. Here’s an example:
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(min_length=2, max_length=50)
price: float = Field(gt=0, le=10000) # must be > 0 and ≤ 10000
quantity: int = Field(ge=0) # must be ≥ 0
name
: must be a string between 2 and 50 characters.price
: must be greater than 0 and less than or equal to 10,000.quantity
: must be a non-negative integer (zero or more).Let’s try to create an item:
item = Item(name="Book", price=100000, quantity=10)
print(item)
⚠️ What Happens Here?
This will raise a validation error because the price
is 100000, which is more than the allowed maximum of 10,000:
pydantic.error_wrappers.ValidationError:
1 validation error for Item
price
ensure this value is less than or equal to 10000 (type=value_error.number.not_le; limit_value=10000)
Pydantic stops invalid data right at the gate — making your code more reliable and secure.
✅ Tip:
Field()
is perfect when you need input validation for APIs, forms, or AI agents — no extra if-else checks needed!
Pydantic makes Python data validation simple, powerful, and fast — all while keeping your code clean and readable. With BaseModel
, you get automatic type checking and parsing. Using Optional
, List
, and Field()
, you can easily define flexible yet strict data structures tailored to your application’s needs. Whether you’re building APIs, data pipelines, or AI agents, Pydantic helps you catch errors early and keep your data consistent. Once you start using it, you’ll wonder how you ever lived without it.