json

FormatValidateConvert

JSON to Python

JSON
Language
Structured output

Result· read-only

—Python

The result appears here.

Generate

JSON to Python: generate Pydantic models from JSON.

Your document never leaves the browser.

Pydantic models, dataclasses or TypedDicts from JSON — in your browser, never uploaded.

Paste a payload and get Python 3.11 classes that parse it. The default is Pydantic v2, which validates as it reads; a dataclass or a TypedDict is one choice away for code that has no Pydantic.

3.11

the Python version the output needs

3

styles: Pydantic v2, dataclass or TypedDict

0

bytes leave your machine

The Pydantic output

Every object in the document becomes a BaseModel subclass, the nested ones first, so each class is defined before a later one refers to it. qty holds whole numbers only, so it is int; price holds 3.5 and 12, so it is float. The file opens with a comment naming the Python version and the pydantic>=2 requirement.

gift-wrap cannot be a Python attribute, so the field is gift_wrap with Field(alias="gift-wrap"), and the model gains populate_by_name=True so your own code can build it with either spelling. It is missing from one line item, so it defaults to None. note is in both, once null, so it is str | None with no default: the key must be there, though it may be null.

1

The sample, an order with two line items, pasted as the source

{
  "order_id": 1042,
  "placed_at": "2026-09-25T10:15:00Z",
  "paid": true,
  "customer": { "name": "Ada Lovelace", "email": "[email protected]" },
  "items": [
    { "sku": "PEN-01", "qty": 2, "price": 3.5, "note": null },
    { "sku": "INK-07", "qty": 1, "price": 12, "note": "Fragile", "gift-wrap": true }
  ]
}
2

The models written for it, in the default Pydantic v2 style

# Generated by myjsoneditor.com — Python 3.11+
# Requires pydantic>=2

from pydantic import BaseModel, ConfigDict, Field


class Customer(BaseModel):
    name: str
    email: str


class Item(BaseModel):
    model_config = ConfigDict(populate_by_name=True)
    sku: str
    qty: int
    price: float
    note: str | None
    gift_wrap: bool | None = Field(default=None, alias="gift-wrap")


class Root(BaseModel):
    order_id: int
    placed_at: str
    paid: bool
    customer: Customer
    items: list[Item]

Three styles

The sample, with Style dataclass

# Generated by myjsoneditor.com — Python 3.11+
# Dataclasses do not turn nested dicts into classes, and cannot tell a null
# field from a missing one: use the Pydantic style when either matters.
# Keys that are not Python names are renamed (see "JSON key"), so
# Class(**data) does not work for those classes.

from dataclasses import dataclass


@dataclass(kw_only=True)
class Customer:
    name: str
    email: str


@dataclass(kw_only=True)
class Item:
    sku: str
    qty: int
    price: float
    note: str | None
    gift_wrap: bool | None = None  # JSON key: "gift-wrap"


@dataclass(kw_only=True)
class Root:
    order_id: int
    placed_at: str
    paid: bool
    customer: Customer
    items: list[Item]

Style

Pydantic v2

Pydantic v2, the default: BaseModel classes that validate types and turn nested dicts into nested models when you call model_validate_json.

Style

dataclass

dataclass: plain @dataclass(kw_only=True) classes from the standard library. The header warns that dataclasses neither convert nested dicts into classes nor tell a null field from a missing one.

Style

TypedDict

TypedDict: type hints over the dicts json.loads already returns, with NotRequired marking a key some records lack. Nothing is checked at run time; a type checker such as mypy or Pyright does the checking.

Names Python will not accept

A key that is a Python keyword gets a trailing underscore, so class becomes class_, and a key starting with a digit gets a prefix, so 2fa becomes field_2fa. In the Pydantic style each renamed field keeps its JSON name as an alias, so reading and writing the document still use the original keys.

An array of mixed values is typed as a union of what was seen, list[str | int] for strings and integers side by side. Timestamps stay str; convert them with datetime.fromisoformat, or change the annotation to datetime and let Pydantic parse them.

1

A keyword, a key starting with a digit, and a mixed list

{ "class": "A", "2fa": true, "ids": ["a", 1] }
2

Each renamed field keeps its JSON name as an alias

# Generated by myjsoneditor.com — Python 3.11+
# Requires pydantic>=2

from pydantic import BaseModel, ConfigDict, Field


class Root(BaseModel):
    model_config = ConfigDict(populate_by_name=True)
    class_: str = Field(alias="class")
    field_2fa: bool = Field(alias="2fa")
    ids: list[str | int]

Your sample stays here

Inference and code generation both run inside this browser tab. The sample is never uploaded, stored on a server or logged, because the page has no server to send it to, and once loaded it carries on working with the connection off.

Read next:

FAQ

Frequently asked questions

Didn’t find your answer?Write to us on the contact page →
Which Python version does the output need?

Python 3.11 or later, as the header comment says. NotRequired, which the TypedDict style uses, joined the standard typing module in 3.11.

Does it support Pydantic v1?

No. The models use names only v2 has, such as ConfigDict and model_config. The dataclass and TypedDict styles need no Pydantic at all.

How do I parse the JSON with these models?

Call Root.model_validate_json(text), with your root class in place of Root. It checks every field and returns nested model instances.

Keyboard shortcuts

Send feedback

Questions, bug reports and feature requests are all welcome. A bug report is easiest to act on with the shape of the document that caused it — never send anything confidential.

Email us

Contact page, in a new tab, so this page stays as it is.

Settings

Indent

The result is written with it — YAML and XML at 2 spaces when it is Tab.

Code text size
14 px

Both panes.

Wrap long lines

Load from a URL

Your browser fetches it directly — the request goes to that site, never to us.