🍱 Lunchbox Hands

JSON → Pydantic Model

Generate Pydantic v2 models with Field aliases from a JSON sample

Paste a JSON sample and get Pydantic v2 models: BaseModel classes with snake_case fields, Field(alias="...") for keys that aren't valid Python identifiers, modern list[X] and X | None annotations, and nested classes defined in dependency order. Everything runs in your browser — nothing is uploaded.

Pydantic code will appear here...

Frequently asked questions

Does this generate Pydantic v1 or v2 models?

Pydantic v2. The generated code uses modern union syntax (str | None instead of Optional[str]), built-in generics (list[str] instead of List[str]), and Field(alias=...) for renamed keys. The class definitions themselves are compatible with both major versions, but the surrounding v2 API differs: v2 renamed .dict() to .model_dump(), .parse_obj() to .model_validate(), and replaced the inner Config class with model_config.

Why do some fields have Field(alias="...")?

JSON keys like "user-id", "1st_place", or "created at" are not valid Python identifiers, and camelCase keys are unidiomatic in Python. The generator converts every key to a snake_case field name and, when that differs from the original key, attaches Field(alias="original-key") so Pydantic still reads the right key from your JSON. By default Pydantic v2 validates using the alias; set model_config = ConfigDict(populate_by_name=True) if you also want to construct models with the Python field names.

What is the difference between "X | None" and "= None" in the output?

They are independent in Pydantic v2. "X | None" only widens the type to accept null — the field is still required, so the key must be present in the JSON. A field only becomes optional when it has a default, like "= None". This tool mirrors your sample: keys that appear with a null value get "| None" but stay required, while keys missing from some objects in an array get both "| None" and a None default.

Why is there no Optional[...] in the generated code?

Optional[X] and X | None mean exactly the same thing; the union form has been available since Python 3.10 and is what current Python style guides and the Pydantic docs prefer. If you are stuck on Python 3.8 or 3.9, add "from __future__ import annotations" at the top of the module and the generated annotations will work there too.

Is my JSON uploaded anywhere?

No. Parsing, type inference, and code generation all run as JavaScript in your browser. Nothing is sent to a server, so it is safe to paste API responses containing real data.

Get weekly dev tools and tips