In many modern Python applications, especially those that handle incoming data (e.g., JSON payloads from an API), ensuring that the data is valid, complete, and properly typed is crucial. Pydantic is a powerful library that allows you to define models for your data using standard Python-type hints and then automatically validate any incoming data against these models. In this example, we’ll showcase how to model a typical use case: a user placing an order for products. We’ll use Pydantic to define User, Product, and Order models, ensuring that data like emails, prices, quantities, and user details adhere to our specified constraints.
Step 1: Install Dependencies
pip install pydantic
pip install pydantic[email]
Use pip install pydantic to install the core library, enabling data validation with Python-type hints. Also, run pip install pydantic[email] for built-in email validation features.
Step 2: Define the Pydantic Models (User, Product, and Order)
from typing import List, Optional
from pydantic import BaseModel, Field, EmailStr, conint, ValidationError
# Define the models
class User(BaseModel):
name: str = Field(..., min_length=1, max_length=50, description="User's full name")
email: EmailStr = Field(..., description="User's email address, validated by Pydantic")
age: Optional[conint(ge=0, le=120)] = Field(None, description="Optional age with a realistic range")
phone_number: Optional[str] = Field(None, pattern=r'^+?[1-9]d{1,14}$', description="Optional phone number, E.164 format")
class Product(BaseModel):
name: str = Field(..., min_length=1, max_length=100)
price: float = Field(..., gt=0, description="Price must be greater than zero")
quantity: conint(gt=0) = Field(..., description="Quantity must be greater than zero")
class Order(BaseModel):
order_id: int = Field(..., gt=0, description="Order ID must be a positive integer")
user: User
products: List[Product] = Field(..., description="A list of products in the order")
# Computed property
@property
def total_cost(self) -> float:
return sum(product.price * product.quantity for product in self.products)
Through the above code, these three Pydantic models, User, Product, and Order, provide a structured, validated approach to managing application data. The user enforces constraints for name, email, optional age, and an optional phone number matching a pattern. The product ensures a valid name length, a positive price, and a non-zero quantity. Finally, the Order ties the user and products together while computing the total cost of the order.
Step 3: Implement Validation in the main() Function
def main():
# Example of a valid user dictionary
user_data = {
"name": "Jane Doe",
"email": "jane.doe@example.com",
"age": 30,
"phone_number": "+1234567890"
}
# Example of product data
products_data = [
{"name": "Keyboard", "price": 49.99, "quantity": 1},
{"name": "Mouse", "price": 19.99, "quantity": 2}
]
# Combine user and products in an order
order_data = {
"order_id": 101,
"user": user_data,
"products": products_data
}
try:
# Instantiate models to trigger validation
valid_user = User(**user_data)
print("User Model:", valid_user)
valid_products = [Product(**pd) for pd in products_data]
print("Product Models:", valid_products)
valid_order = Order(**order_data)
print("Order Model:", valid_order)
print(f"Total cost of the order: {valid_order.total_cost}")
except ValidationError as e:
print("Validation Error:", e)
Now, this main() function simulates receiving data for a user and multiple products, then creates and validates the corresponding User, Product, and Order instances. It demonstrates how Pydantic raises a ValidationError if any data fails validation and prints out validated models and the computed total cost otherwise.
Step 4: Execute the Program
# Run the main() function
main()
We call main() to execute the demonstration, which validates our example user, product, and order data. After running the function, it prints out the validated models and any errors if the data fails validation.
Output
User Model: name='Jane Doe' email='jane.doe@example.com' age=30 phone_number='+1234567890' Product Models: [Product(name='Keyboard', price=49.99, quantity=1), Product(name='Mouse', price=19.99, quantity=2)] Order Model: order_id=101 user=User(name='Jane Doe', email='jane.doe@example.com', age=30, phone_number='+1234567890') products=[Product(name='Keyboard', price=49.99, quantity=1), Product(name='Mouse', price=19.99, quantity=2)] Total cost of the order: 89.97
The output for the code will be as above.
In this example, we demonstrated how Pydantic can define and validate data models for a User, Product, and Order within a real-world workflow. Pydantic ensures that any data fed into these models is correct by specifying field types, constraints, and custom validations. This helps you catch errors early, simplify your code logic, and boost reliability in data-intensive applications.
Here is the Colab Notebook for the above project. Also, don’t forget to follow us on Twitter and join our Telegram Channel and LinkedIn Group. Don’t Forget to join our 75k+ ML SubReddit.
The post A Step-by-Step Tutorial on Robustly Validating and Structuring User, Product, and Order Data with Pydantic in Python appeared first on MarkTechPost.