A Beginner’s Guide to Pydantic: Simple Steps for Data Validation


Are you tired of writing repetitive code to validate user inputs? Do you want to ensure your Python objects have the correct data types and values effortlessly? If so, Pydantic might be the library you've been searching for.
What is Pydantic?
Pydantic is a Python data validation library that uses Python annotations to validate data and enforce type hints at runtime. It's particularly popular in the FastAPI ecosystem but can be used in any Python project that requires data validation.
Why should you use Pydantic?
Before diving into the code, let's understand why Pydantic is valuable:
Type Safety: Catch errors early by ensuring data conforms to expected types
Automatic Validation: Convert and validate input data with minimal code
Clear Documentation: Type hints serve as documentation for your data models
Great IDE Support: Get autocomplete and type checking in your editor
Pydantic vs. Dataclasses: What's the Difference?
Before diving deeper into Pydantic, let's compare it with Python’s built-in dataclass. While both provide structured data models, they serve different purposes:
If you need lightweight data structures without validation, dataclass is a good choice. However, if you want robust validation, serialization, and automatic type enforcement, Pydantic is the better tool.
Getting Started with Pydantic
First, let's install Pydantic:
pip install pydantic
- For more details, refer to the Pydantic Documentation.
Now, let's create our first Pydantic model:
from pydantic import BaseModel, EmailStr, field_validator
class User(BaseModel):
name: str
email: EmailStr
acc_id: int
# CUSTOM VALIDATION for acc_id to ensure it is positive
@field_validator("acc_id")
def valid_acc(cls, value):
if value <= 0:
raise ValueError(f'acc_id must be positive: {value}')
return value
# Create a User instance
user = User(name='Adam', email='adam13@gmail.com', acc_id=123)
print(user.name, user.acc_id, user.email)
print(user)
# Convert the User instance to a JSON string (Serialization)
user_json_str = user.model_dump_json()
print("Serialized JSON:", user_json_str)
# Convert JSON string back to a User object (Deserialization)
import json # Using the json module to prepare the string in correct format
json_str = '{"name": "adam", "email": "adam13@gmail.com", "acc_id": 123}'
user_from_json = User.model_validate_json(json_str)
print("\nDeserialized User:", user_from_json)
In this example, we've created a User model with three fields:
name: A simple string field
email: Using the special EmailStr type for email validation
acc_id: An integer with a custom validator to ensure it's positive
Expected Output
Adam 123 adam13@gmail.com
name='Adam' email='adam13@gmail.com' acc_id=123
Serialized JSON: {"name":"Adam","email":"adam13@gmail.com","acc_id":123}
Deserialized User: name='adam' email='adam13@gmail.com' acc_id=123
The example demonstrates several key features:
Field Validation: Automatic type checking for all fields
Custom Validators: The field_validator decorator for additional validation rules
Serialization: Converting the model to JSON with model_dump_json()
Deserialization: Creating a model from JSON with model_validate_json()
Advanced Features
Field Validators: Create custom validation rules (as shown in the above code)
Nested Models: Compose complex data structures
Custom Types: Define special types (emails, URLs, etc.)
Schema Generation: Auto-generate JSON Schema documentation
Field Customization: Set defaults, constraints, and aliases
Common Pitfalls
Watch out for these common mistakes:
Forgetting Imports: Make sure to import all required types from typing
Mutating Default Values: Be careful with mutable default values (use factory functions if needed)
Overcomplicating Validation: Start simple and add complexity only when necessary
Using Deprecated Methods: If using Pydantic V2, remember that methods like dict() and json() have been replaced with model_dump() and model_dump_json()
Conclusion
Pydantic provides a powerful, yet easy-to-use approach to data validation in Python. By leveraging Python's type hinting system, it offers a clean, intuitive way to ensure your data meets your requirements.
Whether you're building a REST API, processing config files, or just want more robust data structures in your application, Pydantic can help you write more reliable, self-documenting code with less effort.
Give it a try in your next project and experience the benefits of automatic data validation!
Subscribe to my newsletter
Read articles from Maanvi Alung directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
