JSON to Python
Generate Python dataclasses from JSON
JSON Input
Python Output
What is JSON to Python Dataclass Conversion?
JSON to Python dataclass conversion takes a raw JSON object and produces a set of Python dataclass definitions with accurate type annotations. Python's dataclasses module, introduced in PEP 557 (Python 3.7), generates __init__, __repr__, and __eq__ methods from annotated class fields. When you work with JSON APIs, configuration files, or message queues, dataclasses give your data a typed structure that editors and type checkers like mypy can verify at development time.
Python's json.loads() returns plain dicts and lists. These work, but they have no type information: a misspelled key returns None instead of raising an error, and your editor cannot autocomplete field names. Dataclasses solve this by mapping each JSON key to a named, typed field. Nested JSON objects become separate dataclass definitions, arrays become List[T] annotations, and null values become Optional[T] with a default of None.
Writing these definitions by hand is mechanical work. You read the JSON, figure out each field's type from its value, convert keys from camelCase or snake_case to Python conventions, and handle edge cases like nullable fields and mixed-type arrays. A converter does all of this in milliseconds. You paste JSON, get correct dataclass code, and move on.
Why Use a JSON to Python Converter?
Translating JSON structures into Python class definitions by hand means guessing types from sample data, reordering fields so required ones come before optional ones, and updating everything when the API changes. A converter removes that friction.
JSON to Python Use Cases
JSON to Python Type Mapping
Every JSON value maps to a specific Python type annotation. The table below shows how the converter translates each JSON type, with both the typing module syntax (Python 3.7+) and the built-in syntax available from Python 3.10 onward.
| JSON Type | Example | Python (typing) | Python 3.10+ |
|---|---|---|---|
| string | "hello" | str | str |
| number (integer) | 42 | int | int |
| number (float) | 3.14 | float | float |
| boolean | true | bool | bool |
| null | null | Optional[str] | str | None |
| object | {"k": "v"} | @dataclass class | nested model |
| array of strings | ["a", "b"] | List[str] | list[str] |
| array of objects | [{"id": 1}] | List[Item] | list[Item] |
| mixed array | [1, "a"] | List[Any] | list[Any] |
Dataclass Decorator Reference
The @dataclass decorator accepts several parameters that change how the generated class behaves. This reference covers the options most relevant when working with JSON-derived data.
| Decorator / Field | Behavior | Use When |
|---|---|---|
| @dataclass | Generates __init__, __repr__, __eq__ from field annotations | Standard dataclasses |
| @dataclass(frozen=True) | Makes instances immutable (hashable, no attribute reassignment) | Config objects, dict keys |
| @dataclass(slots=True) | Uses __slots__ for lower memory and faster attribute access | Python 3.10+, large datasets |
| @dataclass(kw_only=True) | All fields require keyword arguments in __init__ | Python 3.10+, many fields |
| field(default_factory=list) | Sets a mutable default without sharing state between instances | List/dict/set defaults |
dataclass vs Pydantic vs TypedDict
Python has three common ways to define typed structures from JSON. Each fits a different use case. Dataclasses are the standard library option with zero dependencies. Pydantic adds runtime validation. TypedDict annotates plain dicts without creating a new class.
Code Examples
These examples show how to use generated dataclasses in Python, how to produce them programmatically from JavaScript, and how to use alternative approaches like Pydantic and CLI tools.
from dataclasses import dataclass
from typing import List, Optional
import json
@dataclass
class Address:
street: str
city: str
zip: str
@dataclass
class User:
id: int
name: str
email: str
active: bool
score: float
address: Address
tags: List[str]
metadata: Optional[str] = None
raw = '{"id":1,"name":"Alice","email":"alice@example.com","active":true,"score":98.5,"address":{"street":"123 Main St","city":"Springfield","zip":"12345"},"tags":["admin","user"],"metadata":null}'
data = json.loads(raw)
# Reconstruct nested objects manually
addr = Address(**data["address"])
user = User(**{**data, "address": addr})
print(user.name) # -> Alice
print(user.address) # -> Address(street='123 Main St', city='Springfield', zip='12345')// Minimal JSON-to-Python-dataclass generator in JS
function jsonToPython(obj, name = "Root") {
const classes = [];
function infer(val, fieldName) {
if (val === null) return "Optional[str]";
if (typeof val === "string") return "str";
if (typeof val === "number") return Number.isInteger(val) ? "int" : "float";
if (typeof val === "boolean") return "bool";
if (Array.isArray(val)) {
const first = val.find(v => v !== null);
return first ? `List[${infer(first, fieldName + "Item")}]` : "List[Any]";
}
if (typeof val === "object") {
const clsName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
build(val, clsName);
return clsName;
}
return "Any";
}
function build(obj, cls) {
const fields = Object.entries(obj).map(([k, v]) => ` ${k}: ${infer(v, k)}`);
classes.push(`@dataclass\nclass ${cls}:\n${fields.join("\n")}`);
}
build(obj, name);
return classes.join("\n\n");
}
const data = { id: 1, name: "Alice", scores: [98, 85] };
console.log(jsonToPython(data, "User"));
// @dataclass
// class User:
// id: int
// name: str
// scores: List[int]from pydantic import BaseModel
from typing import List, Optional
class Address(BaseModel):
street: str
city: str
zip: str
class User(BaseModel):
id: int
name: str
email: str
active: bool
score: float
address: Address
tags: List[str]
metadata: Optional[str] = None
# Pydantic parses and validates JSON in one step
raw = '{"id":1,"name":"Alice","email":"alice@example.com","active":true,"score":98.5,"address":{"street":"123 Main St","city":"Springfield","zip":"12345"},"tags":["admin","user"],"metadata":null}'
user = User.model_validate_json(raw)
print(user.name) # -> Alice
print(user.model_dump_json()) # -> re-serializes to JSON# Install the generator
pip install datamodel-code-generator
# Generate dataclasses from a JSON file
datamodel-codegen --input data.json --output models.py --output-model-type dataclasses.dataclass
# Generate Pydantic models instead
datamodel-codegen --input data.json --output models.py
# From a JSON string via stdin
echo '{"id": 1, "name": "Alice", "tags": ["admin"]}' | \
datamodel-codegen --output-model-type dataclasses.dataclass
# Output:
# @dataclass
# class Model:
# id: int
# name: str
# tags: List[str]