Day 3 · ~13m

Your First BaseModel

Creating models, defining fields, and instantiating validated objects.

🧑‍💻

I've been using plain dictionaries to pass data around. What's wrong with that?

👩‍🏫

Nothing — until something goes wrong. A dictionary will happily let you store {"age": "banana"} and you won't find out until your code crashes three functions later. Pydantic's BaseModel catches that the moment the data arrives:

from pydantic import BaseModel

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

user = User(name="Alice", age=30, email="alice@example.com")
print(user.name)   # "Alice"
print(user.age)    # 30

You declare the fields and their types. Pydantic checks everything when you create the instance. If age isn't an integer (or something that can be converted to one), it raises a ValidationError immediately.

🧑‍💻

What happens if I pass the wrong type? Like a string for age?

👩‍🏫

Pydantic is smart about it. It tries to coerce the value first. If you pass "30" for age, it converts it to 30 — that's a reasonable conversion. But if you pass "banana", there's no sensible conversion to int, so it raises an error:

# This works — "30" gets coerced to 30
user = User(name="Bob", age="30", email="bob@example.com")
print(user.age)       # 30
print(type(user.age)) # <class 'int'>

# This fails — "banana" can't become an int
try:
    user = User(name="Bob", age="banana", email="bob@example.com")
except Exception as e:
    print(e)  # validation error for age
🧑‍💻

So Pydantic models are just like regular classes but with automatic type checking?

👩‍🏫

Exactly. You can access fields with dot notation, pass models to functions, and use them anywhere you'd use a regular object. But you also get validation, serialization, and type safety for free:

class Product(BaseModel):
    name: str
    price: float
    in_stock: bool

item = Product(name="Widget", price=9.99, in_stock=True)
print(f"{item.name}: ${item.price}")  # "Widget: $9.99"

Every field is validated on creation. You define the shape of your data once, and Pydantic enforces it everywhere.

🧑‍💻

Can I create a model from a dictionary? Like if I'm getting JSON from an API?

👩‍🏫

Yes — use the double-star ** unpacking syntax. If you have a dictionary with the right keys, it works directly:

data = {"name": "Widget", "price": 9.99, "in_stock": True}
item = Product(**data)
print(item.name)  # "Widget"

Or use model_validate() which does the same thing:

item = Product.model_validate(data)

This is the pattern you'll use constantly — data comes in as a dictionary (from JSON, a database row, a form submission), you validate it through a model, and from that point on you have a clean, typed object.

Practice your skills

Sign up to write and run code in this lesson.

Already have an account? Sign in