JSON → Python
Generate Python dataclasses from a JSON sample.
Private by design. Your input never leaves this browser. Conversions run locally on your device.
What this tool handles
- Emits @dataclass definitions with type hints, one class per nested object.
- Keys that are not valid Python identifiers are skipped and listed in a comment.
- Null values in the sample produce Optional fields.
Example
JSON sample
{"id":1,"name":"Ada","manager":null}
Python
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Optional
@dataclass
class Root:
id: int
name: str
manager: Optional[Any] = None
When you would use it
- Writing a client for a REST endpoint — A captured response becomes @dataclass definitions to hang a hand-written client off, with each nested class defined above the class that refers to it.
- Modelling a webhook payload — One delivered body gives you the classes to type the handler signature with, instead of reading keys out of a dict and guessing which of them are always present.
- Moving a script off raw dictionaries — A script that indexes into data["items"][0]["id"] can be lifted onto generated classes, so a renamed key becomes a type error rather than a KeyError at runtime.
Common questions
Can it emit TypedDict, Pydantic or attrs models?
No, only standard-library @dataclass definitions with typing hints. Nothing is validated at runtime; the output is a typed container, not a parser.
Why are the attributes in a different order from the JSON?
Optional and nullable fields are given a default of None, and Python requires defaulted fields to come last, so they are moved to the end of the class. Constructing an instance positionally therefore does not follow the original key order.
Are the original key names kept?
Attribute names are converted to snake_case, so lastSeen becomes last_seen and HTTPStatus becomes http_status. No metadata mapping an attribute back to its JSON key is emitted, so a from_dict loader has to apply the rename itself.
How are numbers typed?
A whole number in the sample becomes int and a fractional one becomes float, so a price that happens to be 10 in your sample is typed int even though the endpoint can return 10.5. Only a position that held genuinely different types produces Union, as in Union[int, str].
Related tools
- JSON → TypeScript — Generate TypeScript interfaces or types from a JSON sample.
- JSON → Zod — Generate a Zod schema from a JSON sample.
- JSON → Go — Generate Go structs with json tags from a JSON sample.
- JSON → SQL — Generate a CREATE TABLE statement from flat JSON rows.
- JSON → JSON Schema — Infer a JSON Schema from a sample document.
- Convert any format — Pick an input format and an output format and convert between any pair.