Structured Output / pydantic
AI/LLMextract.py
from pydantic import BaseModel, Field
from openai import OpenAI
client = OpenAI()
class Contact(BaseModel):
"""One person pulled out of free-form text."""
name: str
email: str | None = None
role: str | None = Field(None, description="job title if mentioned")
def extract_contact(text: str) -> Contact:
resp = client.responses.parse(
model="gpt-4o-mini",
input=[
{"role": "system", "content": "Extract the contact. Leave unknown fields null."},
{"role": "user", "content": text},
],
text_format=Contact, # schema is enforced by the API
)
return resp.output_parsed # already a validated Contact
main.py — FastAPI
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class ExtractIn(BaseModel):
text: str
@app.post("/extract", response_model=Contact)
def extract(body: ExtractIn) -> Contact:
return extract_contact(body.text) # FastAPI validates in AND out