Pydantic Model from JSON

Generate a Python Pydantic v2 model from any JSON sample.

Parses a JSON object and produces a Pydantic v2 BaseModel class with correct field types, Optional annotations, list types, and nested model classes for sub-objects. Outputs ready-to-paste Python code. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

Which Pydantic version is targeted?

Pydantic v2 syntax with BaseModel and standard typing annotations (Optional, list, Any). The output is also valid under v1 for the basic field forms shown.

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 constraintsField(gt=0) for positive integers, Field(max_length=255) for strings
  • Validators@field_validator for custom business rules (e.g., valid email format)
  • AliasesField(alias="camelCaseKey") when the JSON uses camelCase but you prefer snake_case
  • Model configmodel_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.