Skip to main content

Nested Structured Output with Pydantic

In this lesson, you'll learn how to parse complex, nested responses into structured Python objects using Pydantic models and the OpenAI parse() method.

Prerequisites

Install dependencies:

pip install openai pydantic

The Code

from openai import OpenAI
from pydantic import BaseModel

client = OpenAI()

# Define one day's plan
class DayPlan(BaseModel):
day: int
activities: list[str]
location: str

# Define overall trip plan
class TravelItinerary(BaseModel):
destination: str
days: list[DayPlan]
notes: str

# Send the request and expect a response in the defined format
response = client.responses.parse(
model="gpt-4o-mini",
input=[
{
"role": "system",
"content": "You are a travel assistant. Generate a daily itinerary based on the user's request."
},
{
"role": "user",
"content": "Plan a 3-day trip to Indonesia with historical and food experiences."
}
],
text_format=TravelItinerary,
)

trip_plan = response.output_parsed

print(f"\U0001F4CD Destination: {trip_plan.destination}\n")
for day in trip_plan.days:
print(f"Day {day.day} - {day.location}")
for idx, activity in enumerate(day.activities, start=1):
print(f" {idx}. {activity}")
print()

print(f"\U0001F4DD Notes: {trip_plan.notes}")

Explanation

  • Defines nested models (DayPlan inside TravelItinerary).
  • Uses OpenAI’s parse() method to directly convert raw responses to usable structured objects.
  • Enables easy iteration and rendering of deeply nested structured data.

Use Case

Ideal for:

  • Itinerary planners
  • Form-based output for apps
  • Multi-level object parsing (e.g., resumes, reports, schedules)