JSON to Python — TypedDict, dataclass or Pydantic model from a sample

Paste a JSON sample and get Python type definitions for it, as TypedDict classes, dataclasses or Pydantic models, with a class for each nested object and optional fields marked from what the sample shows.

Live demo · real result from this tool

Python

from typing import TypedDict  class Address(TypedDict):    city: str    postcode: str  class User(TypedDict):    id: int    name: str    email: str    active: bool    roles: list[str]    address: Address    lastLogin: None 

Processed on your device — nothing is uploaded.

How to use JSON to Python

  1. Paste a sample into JSON. For lists, paste several items so optional fields can be detected.
  2. Set the Class name for the top-level class.
  3. Choose a Style: TypedDict, dataclass or Pydantic model.
  4. Copy or download models.py. Nested classes come first, so the file runs as it is.

What it does and when to use it

When a Python service consumes a JSON API, typed classes let your editor autocomplete fields and let a type checker catch typos such as order["totla"]. Writing those classes for a large response takes a while and is easy to get subtly wrong. Paste one real response and you get definitions to start from.

The same sample can produce Go structs or TypeScript interfaces if other services use it. To check later responses against a fixed contract instead of Python types, write a schema and test with the JSON Schema validator.

How it works

The tool reads the sample in your browser and builds one shape from it. Items in an array are merged, so a key missing from some items is optional: NotRequired[...] in TypedDict, or | None = None in dataclass and Pydantic, where optional fields are moved after required ones because Python needs defaults last. Whole numbers become int, a mix of whole and decimal numbers becomes float, and values that change type become a union such as str | int. Each nested object becomes a class named after its key in singular form, so items gives Item.

Worked examples

An order sample, Class name Order, style TypedDict (abridged):

from typing import Any, NotRequired, TypedDict


class Item(TypedDict):
    sku: str
    price: float
    gift: NotRequired[bool]


class Order(TypedDict):
    order_id: str
    total: float
    coupon: None
    customer: Customer
    items: list[Item]
    tags: list[Any]

gift appears in only one of two items, so it is NotRequired. coupon was null and tags was empty, so both need a real type from you.

Pydantic style for {"orderId": "A-17", "class": "gold", ...}:

class Order(BaseModel):
    order_id: str = Field(alias="orderId")
    class_: str = Field(alias="class")
    items: list[Item]

Limits and tips

  • Types reflect only your sample. A string that holds a date stays str; change it to datetime by hand if you want parsing.
  • With Pydantic aliases, build models with Order.model_validate(data); passing order_id= directly needs populate_by_name in the model config.

Frequently asked questions

Which style should I pick?
TypedDict if you keep working with plain dicts from json.loads and only want type checking (mypy, Pyright). dataclass if you build objects in your own code. Pydantic if you want the data validated and converted at runtime, for example in FastAPI.
Which Python version does the output need?
The code uses list[str] and str | None, so Python 3.10 or later. TypedDict output with optional fields imports NotRequired from typing, which arrived in Python 3.11; on 3.10, import it from typing_extensions instead. The Pydantic output is written for Pydantic 2.
Can I load JSON straight into the dataclass?
Only partly. Field names are converted to snake_case, so Order(**data) fails when the JSON key is orderId, and nested dicts are not turned into nested dataclasses for you. Map the keys yourself, use a library such as dacite, or choose the Pydantic style, which keeps the original key as an alias.
Why is a field typed None or list[Any]?
The sample only had null for that field, or only an empty list, so there was no value to learn the type from. Replace None or Any with the real type, keeping | None if the field can be null.
What happens to keys that are not valid Python names?
In TypedDict style, a class with any key such as content-type, class or 2fa is written in the functional form, TypedDict("Name", {...}), so the original keys are kept. In dataclass and Pydantic style, names become snake_case, a trailing underscore is added to Python keywords (class_), and Pydantic adds Field(alias=...) with the original key.

Written by the ToolsRift team · Last updated

Pages are drafted with AI assistance and checked by automated tests. How we write and check pages.

Was this tool useful?

Report a problem

Start typing to search every tool.

↑ ↓ to moveEnter to openEsc to close