07 — Getting Started with Pydantic
What is Pydantic?
Pydantic is a Python library for data validation and settings management, built on top of standard Python type hints. You describe the shape of your data once as a class, and Pydantic parses and validates any input against it — raising a clear, specific error the moment something does not match, instead of letting a bad value quietly propagate into your code.
Pydantic is used throughout modern Python tooling, including FastAPI, most LLM structured-output libraries, and countless configuration systems.
Why this matters for computer vision: camera settings, dataset annotation files, and lab-parameter files are all just structured data. Validating them with Pydantic catches a typo'd resolution or a missing field before a long capture or training run starts, not halfway through it.
1. Install Pydantic
With your course virtual environment activated:
pip install pydanticCheck the installed version:
python3 -c "import pydantic; print(pydantic.VERSION)"This tutorial uses Pydantic v2, the current major version.
2. Define Your First Model
A Pydantic model is a class that inherits from BaseModel, with each field written as a type-annotated attribute:
from pydantic import BaseModel
class CameraConfig(BaseModel):
name: str
width: int
height: int
fps: floatCreate an instance by passing keyword arguments:
cam = CameraConfig(name="pi_camera", width=1280, height=720, fps=30.0)
print(cam)name='pi_camera' width=1280 height=720 fps=30.0
3. Validation in Action
Pydantic coerces compatible values to the declared type. A numeric string is parsed into an int automatically:
cam = CameraConfig(name="pi_camera", width="1280", height=720, fps=30.0)
print(type(cam.width))<class 'int'>
But a value that cannot be converted raises a ValidationError that points at the exact field:
CameraConfig(name="pi_camera", width="not-a-number", height=720, fps=30.0)pydantic_core._pydantic_core.ValidationError: 1 validation error for CameraConfig
width
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='not-a-number', input_type=str]
4. Optional Fields & Defaults
Give a field a default value to make it optional, and use Optional[...] when the field may legitimately be None:
from typing import Optional
from pydantic import BaseModel
class CameraConfig(BaseModel):
name: str
width: int = 1280
height: int = 720
fps: float = 30.0
device: Optional[str] = NoneNow a model can be created with just the required field:
cam = CameraConfig(name="pi_camera")5. Nested Models
Models can contain other models. Pydantic validates nested data recursively, including when it is passed as a plain dictionary:
class ROI(BaseModel):
x: int
y: int
width: int
height: int
class CameraConfig(BaseModel):
name: str
roi: Optional[ROI] = None
cam = CameraConfig(name="pi_camera", roi={"x": 0, "y": 0, "width": 640, "height": 480})
print(cam.roi.width)6. Custom Validators
Type checking alone cannot express rules such as "must be positive." Use field_validator for that:
from pydantic import BaseModel, field_validator
class CameraConfig(BaseModel):
width: int
height: int
@field_validator("width", "height")
@classmethod
def must_be_positive(cls, v):
if v <= 0:
raise ValueError("must be a positive integer")
return vNow CameraConfig(width=0, height=480) raises a ValidationError with your custom message instead of silently accepting a useless resolution.
7. Converting To/From JSON
Every model can serialize itself to a Python dict or a JSON string:
cam = CameraConfig(name="pi_camera", width=1280, height=720, fps=30.0)
print(cam.model_dump())
print(cam.model_dump_json())And parse a model back out of a JSON config file:
import json
with open("camera_config.json") as f:
cam = CameraConfig(**json.load(f))model_dump() and model_dump_json() are the Pydantic v2 methods used in this tutorial. If you see .dict() or .json() in older examples online, that is the deprecated Pydantic v1 API.
Good Habits
- Use a Pydantic model for any config file, lab-parameter file, or API payload — not just function arguments
- Prefer specific types (
int,float,Literal[...]) overAnyso mistakes get caught, not passed through - Let
ValidationErrorsurface and stop the program rather than catching and silently ignoring it - Validate data as close as possible to where it enters your program — e.g. a single
load_config()function
Next Steps
Use a Pydantic model to validate the configuration file for your next lab (camera settings, ROI, or detection thresholds) before wiring it into your capture or inference script.