Guide
Pydantic v2 models and dataclasses from JSON
Python code that consumes JSON usually ends up with dictionaries everywhere and KeyError surprises. Modelling the data with Pydantic or dataclasses gives you attribute access, editor completion and, with Pydantic, validation at the boundary. This generator writes those models from a sample, including the awkward parts: keys that are not valid Python names, optional fields and nested lists.
Pydantic or dataclasses
Choose Pydantic v2 when the data comes from outside — an API, a webhook, a user upload. User.model_validate(data) checks every field, converts compatible values (the string “5” to an int, an ISO string to a datetime) and raises a clear error listing every problem. Choose dataclasses for internal data or scripts where you want no dependency; they give structure and type hints but do no checking at runtime.
Names and aliases
Python attributes are snake_case, so userName becomes user_name and content-type becomes content_type. Python keywords and common builtins such as class, type, id and list get a trailing underscore. In Pydantic, any attribute whose name differs from the key gets Field(alias="…"), and the class enables populate_by_name, so you can build instances in Python with the attribute names while JSON still uses the original keys. Dataclasses have no alias mechanism, so a comment records the key.
Optional fields and ordering
A key missing from any sample becomes T | None = None. Values that are null but always present are typed T | None without a default. Fields with defaults are placed after required ones, which dataclasses require and which keeps Pydantic models easy to read. The from __future__ import annotations line lets the X | None syntax work on Python 3.8 and 3.9 and lets classes refer to each other in any order.
Dates and loose values
With date types on, ISO 8601 timestamps become datetime and plain dates date; Pydantic parses them for you. Values that were always null or changed type become Any, imported only when used.
Using the models in FastAPI
Declare a model as a parameter type and FastAPI validates request bodies against it and documents it in the OpenAPI page automatically: async def create(user: User). As a response_model, it filters what you return to exactly the declared fields.
A worked example
The sample user produces four classes in the order Address, Item, Order, User, so each is defined before it is used. The order’s coupon, present in only one order, becomes coupon: str | None = None and sits after order_id, total and items.
Tightening the models
Add constraints the sample cannot show: EmailStr for emails, Field(gt=0) for positive totals, Literal["active", "closed"] for status values. Then keep one real payload in a test so a changed API fails loudly in CI rather than quietly in production.
Lists at the root
When the JSON is a list of records, the generated class describes one record. In Pydantic v2, validate the whole list with a TypeAdapter(list[User]), which gives the same error reporting as a model; with dataclasses, build each item in a list comprehension.
Related tools
Generate the frontend types with JSON to TypeScript, turn an API example into Python code with cURL to Fetch, inspect payloads in the JSON Formatter, or move settings files around with the TOML Converter.
Checked against the current version of the JSON to Pydantic & dataclass on .

