JSON → Python

Class:
JSON Input
Loading editor…
Python Models
Loading editor…

JSON to Python

Paste any JSON and get typed Python instantly. Choose the style that fits your project — a plain @dataclass, a TypedDict for type-checking raw dicts, or a Pydantic BaseModel for runtime validation — and nested objects become their own classes automatically.

Nested classes
Deep objects become separate named classes.
3 styles
Dataclass, TypedDict, or Pydantic BaseModel.
Auto aliasing
Pydantic fields keep the original key via alias=.
Client-side
No data is uploaded. Everything runs in your browser.

Choosing a Style

Dataclass — a plain @dataclass with snake_case attribute names. Best when you just need a typed container with no validation or serialization built in.

TypedDict — a structural type for a plain dict, generated with the functional syntax (TypedDict("Root", {...})) so the exact original JSON keys are preserved as dict keys, even if they contain characters that aren't valid Python identifiers. Best when your code already works with dicts (e.g. straight from json.load) and you just want static type checking on top.

Pydantic — a BaseModel with snake_case attribute names, runtime type validation, and automatic parsing from JSON. When a JSON key isn't already snake_case (e.g. userId), the field gets Field(alias="userId") so Root.parse_obj(data) still works with the original key.

How Types Are Inferred

Input JSON:

{
  "userId": 1,
  "isActive": true,
  "score": 9.5,
  "tags": ["admin", "editor"],
  "avatar": null
}

Generated (Pydantic):

from pydantic import BaseModel, Field
from typing import List, Optional, Any

class Root(BaseModel):
    user_id: int = Field(alias="userId")
    is_active: bool = Field(alias="isActive")
    score: float
    tags: List[str]
    avatar: Optional[Any] = None

Whole numbers become int, decimals become float, strings become str, booleans become bool. A field that is null in the JSON, or missing entirely across a merged array of objects, becomes Optional[T] with a default of None (for TypedDict, a missing key becomes NotRequired[T] instead, keeping the required/optional and nullable distinction separate).

Nested objects generate their own class, referenced by a forward-reference string (e.g. "Address") so classes can be emitted in any order without Python raising a NameError at import time. Arrays of objects become List["ClassName"], with the class name derived from the singularized key.

Field Ordering and Naming Rules

@dataclass requires every field without a default to come before any field with one, or Python raises a SyntaxError. The generator automatically reorders fields — required fields first, optional (defaulted) fields after — while preserving their relative order within each group. Pydantic's BaseModel has no such restriction, since its constructor accepts keyword arguments only, so field order there always matches the original JSON.

For dataclass and Pydantic output, JSON keys are converted to idiomatic snake_case (zipCodezip_code) and Python keywords get a trailing underscore (classclass_). TypedDict output skips this conversion entirely and keeps the literal JSON key, since a TypedDict's keys must exactly match the runtime dict's keys to type-check correctly.

Frequently Asked Questions

Why does TypedDict use a different syntax than the other styles?

TypedDict is generated with the functional syntax — TypedDict("Root", {"key": type}) — instead of a class body, because a TypedDict's keys must exactly match the real dict's keys at runtime. The functional syntax lets us keep the original JSON key even when it isn't a valid Python identifier (contains a hyphen, starts with a digit, etc.), which the class-body syntax can't do.

What does the alias= on Pydantic fields do?

It tells Pydantic to read the original JSON key name during parsing while exposing an idiomatic snake_case attribute in Python. It's added automatically whenever the converted field name differs from the source JSON key.

Why are some fields Optional with a default of None?

A field is made Optional and given a None default when its value is null in the JSON, or when it's missing from some objects in a merged array. This lets the class be constructed even when that field isn't present.

Does this handle deeply nested JSON?

Yes. Each nested object generates its own class recursively to any depth, referenced through a quoted forward-reference string so definition order never causes a runtime error.

Do I need to install anything to use the Pydantic or TypedDict output?

Pydantic output requires the pydantic package. TypedDict's NotRequired requires Python 3.11+, or the typing_extensions backport on older versions. Dataclass output only needs the standard library.

Is my JSON uploaded anywhere?

No. The entire conversion runs in your browser with no network requests. Nothing is transmitted.

More Tools