Pydantic model from JSON
When you parse JSON from an API, an LLM’s structured output, or a config file,
a Pydantic model gives you validation, type hints, and editor autocompletion for
free. Writing those models by hand for nested data is tedious. This tool takes a
JSON sample and generates a complete set of Pydantic v2 BaseModel classes —
one for the root and one for each nested object — with correct types and
Optional annotations.
How it works
The generator walks your parsed JSON and maps each value to a Python type:
strings to str, integers to int, floats to float, booleans to bool,
nulls to Optional[...] = None, and arrays to list[...] based on the first
element. Whenever it encounters a nested object, it creates a new BaseModel
class named after the field and references it by name. Classes are emitted in
dependency order — innermost models first — so the resulting file is valid
Python you can run as-is. Arrays of objects merge their keys so fields absent
from some items are correctly marked optional.
Example: an API response with nested objects
Paste this JSON sample:
{
"id": 42,
"name": "Alice",
"email": null,
"address": {
"street": "123 Main St",
"city": "Springfield",
"zip": "12345"
},
"tags": ["admin", "verified"]
}
The generator produces:
from pydantic import BaseModel
from typing import Optional
class Address(BaseModel):
street: str
city: str
zip: str
class Root(BaseModel):
id: int
name: str
email: Optional[str] = None
address: Address
tags: list[str]
email is Optional[str] because it was null in the sample. Address is generated as a separate class and referenced by name. tags becomes list[str] because the first element is a string.
What happens with arrays of objects
When a field holds an array of objects, the generator inspects every item and merges their keys. A field that appears in some items but not others becomes Optional. For example:
{
"results": [
{"id": 1, "score": 9.5},
{"id": 2, "score": null, "note": "pending"}
]
}
Produces a Results model with id: int, score: Optional[float] = None, and note: Optional[str] = None — because note was absent from the first item and score was null in the second.
After generation: common next steps
The generated code is a structural skeleton. In a real project you would typically add:
- Field constraints —
Field(gt=0)for positive integers,Field(max_length=255)for strings - Validators —
@field_validatorfor custom business rules (e.g., valid email format) - Aliases —
Field(alias="camelCaseKey")when the JSON uses camelCase but you prefer snake_case - Model config —
model_config = ConfigDict(populate_by_name=True)if you need both name and alias access
The generated imports are from pydantic import BaseModel and from typing import Optional — both available in any Python 3.9+ environment with Pydantic v2 installed.