Skip to course content
Free generative AI app course

Generative AI Application Development with Python

Unit 08.02: Extraction with a schema you can check

Extraction is where a model's output becomes a record in your system.

A schema with bounds, not just types

Four extractions against a schema with a pattern and a positivity constraint.

The code validates each.

from pydantic import BaseModel, Field, ValidationError
from typing import Optional


class Invoice(BaseModel):
    invoice_id: str = Field(pattern=r"^INV-\d+$")
    amount: float = Field(gt=0)
    currency: str = Field(pattern=r"^[A-Z]{3}$")
    due_date: Optional[str] = None


EXTRACTIONS = [
    {"invoice_id": "INV-1187", "amount": 240.0, "currency": "USD"},
    {"invoice_id": "1187", "amount": 240.0, "currency": "USD"},
    {"invoice_id": "INV-1187", "amount": "two hundred", "currency": "USD"},
    {"invoice_id": "INV-1187", "amount": -240.0, "currency": "USD"},
]
for raw in EXTRACTIONS:
    try:
        print(f"OK    {Invoice(**raw)}")
    except ValidationError as exc:
        e = exc.errors()[0]
        print(f"FAIL  {str(raw)[:52]:54} {e['loc'][0]}: {e['type']}")

# Extraction is where a model's output becomes a record in your system. A
# negative amount and a malformed id both parse as JSON, and both would be
# written to a database by any code that only checked the parse.

The negative amount and the malformed id both parse as JSON and would be written to a database by any code that checked only the parse. A negative invoice amount is not a data error to be cleaned later - it is a record that will be reconciled against something real.

gt=0 and the id pattern are the two lines that turn a plausible dict into a usable one.

The mistake this prevents

The mistake is extracting into a dict and inserting it. The insert succeeds, the row is wrong, and the error surfaces weeks later in a report nobody can trace back to a model call.

Takeaway

Validate extracted records with bounds and patterns before they become rows. A parse tells you the shape; only the schema tells you the values are usable.