JSON to Python

Generate Python classes from any JSON object. Choose between @dataclass, TypedDict, or Pydantic v2 BaseModel.

stdlib @dataclass — no dependencies

Which Python type should I use?

dataclassTypedDictPydantic v2
Runtime validationNoNoYes — raises ValidationError
Dependenciesstdlibstdlibpip install pydantic
MutationYes (mutable)YesOptional (frozen=True)
JSON serializationManual / json.dumpsManualmodel.model_dump_json()
Field defaultsfield(default=…)Not required keysField(default=…)
ORM integrationNoNoYes (SQLModel, etc.)
Best forData pipelines, dataclassesType hints only, dictsAPIs, validation, serialization

Pydantic v2 — Parse and Validate JSON

python
from pydantic import BaseModel
from typing import Any

class Address(BaseModel):
    city: str
    country: str

    model_config = {"extra": "forbid"}

class Root(BaseModel):
    name: str
    email: str
    age: int
    active: bool
    tags: list[str]
    address: Address

    model_config = {"extra": "forbid"}

import json

# Parse from JSON string
data = json.loads('{"name":"Ravi","email":"ravi@example.com","age":28,"active":true,"tags":["dev"],"address":{"city":"Surat","country":"IN"}}')
obj = Root.model_validate(data)
print(obj.name)   # => Ravi
print(obj.address.city)  # => Surat

# Serialize back to JSON
print(obj.model_dump_json(indent=2))

@dataclass — Lightweight, No Dependencies

python
from __future__ import annotations
from dataclasses import dataclass
import json
from typing import Any

@dataclass
class Address:
    city: str
    country: str

@dataclass
class Root:
    name: str
    email: str
    age: int
    active: bool
    tags: list[str]
    address: Address

# Instantiate directly
addr = Address(city="Surat", country="IN")
user = Root(name="Ravi", email="ravi@example.com", age=28,
            active=True, tags=["dev"], address=addr)
print(user.name)   # => Ravi
print(user.address.city)  # => Surat

# Note: dataclasses don't auto-parse from dict.
# Use dacite for dict-to-dataclass mapping:
# pip install dacite
from dacite import from_dict
user2 = from_dict(Root, data_dict)

Frequently Asked Questions

@dataclass creates real class instances with __init__, __repr__, and optional __eq__. TypedDict is purely a type hint — at runtime it is just a plain dict. TypedDict adds zero overhead but provides no runtime checking. Use TypedDict when you are passing dicts between functions and just want IDE type checking.

Yes — call Root.model_json_schema() to get a JSON Schema from your Pydantic model. This is the reverse of what this tool does. Combined workflow: JSON → this tool → Pydantic model → .model_json_schema() → validated schema.

With Pydantic: items = [Root.model_validate(item) for item in json.loads(array_str)]. With @dataclass + dacite: items = [from_dict(Root, item) for item in data]. There is no magic bulk parser for vanilla dataclasses.

Any appears for fields where the value is null (type unknown), empty arrays (element type unknown), or arrays of mixed types. After generating, replace Any with the correct specific type from your domain knowledge.

Currently all inferred fields are required. If a field can be None in your data, change str to Optional[str] (or str | None in Python 3.10+) and add a default value: name: str | None = None.

Related Tools