JSON to Python Dataclass
Generate Python dataclasses from JSON instantly. Supports @dataclass, Pydantic v2 BaseModel, and TypedDict. Handles nested objects, arrays, optional fields, and custom root class names. Free, runs in your browser.
- Runs in your browser
- Your data never leaves your browser
- Free · No Sign-Up
Scan with WeChat to share this tool
Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.
Type Mapping
null→Optional[Any] = None- string →
str - integer →
int - float →
float - boolean →
bool - array →
List[T] - mixed array →
List[Union[T1, T2]] - nested object → separate class
Example
Given this JSON:
{"user": {"first_name": "Alice", "age": 30}, "tags": ["admin"], "note": null}
The tool generates (@dataclass mode):
from dataclasses import dataclass
from typing import Any, List, Optional
@dataclass
class User:
first_name: str
age: int
@dataclass
class Root:
user: User
tags: List[str]
note: Optional[Any] = None
Example: Nested Objects and Missing Keys
Input:
{"id": 7, "title": "Release notes", "author": {"name": "Alice", "email": null}, "tags": ["python", "json"], "score": 4.5, "comments": [{"user": "bob", "text": "nice"}, {"user": "carol"}]}
Output in @dataclass mode:
from dataclasses import dataclass
from typing import Any, List, Optional
@dataclass
class Author:
name: str
email: Optional[Any] = None
@dataclass
class CommentsItem:
user: str
text: Optional[str] = None
@dataclass
class Root:
id: int
title: str
author: Author
tags: List[str]
score: float
comments: List[CommentsItem]
Classes are ordered so that each one is defined before it is used. text is missing from the second comment, so it becomes Optional[str] = None.
dataclass, Pydantic or TypedDict
The three modes describe the same shape but behave differently at runtime (checked with Python 3.12 and Pydantic 2.13):
root = Root(**json.loads(raw))
type(root.author) # <class 'dict'>, not Author
root = Root.model_validate(json.loads(raw)) # Pydantic mode
root.comments[1] # CommentsItem(user='carol', text=None)
- @dataclass does not validate or convert.
Root(**data)keeps nested objects as plain dicts and accepts wrong types. Use it when the data is already trusted, or convert nested fields yourself. - Pydantic validates types and builds nested models; use it for API responses you do not control.
model_validate_json(raw)parses and validates in one step. - TypedDict only describes dict types for a type checker; nothing is checked at runtime. Every key is required by default, so the tool marks a key that is missing from some items as
NotRequired[...](PEP 655,typingin Python 3.11+,typing_extensionsbefore that).Optional[...]only means the value may beNone; the key would still be required.
Example: TypedDict with Missing Keys
Two products where note is null in the first and absent from the second, and discount only appears in the second (root class name Product, TypedDict mode):
[{"id": 1, "sku": "PEN-01", "price": 2, "note": null}, {"id": 2, "sku": "INK-07", "price": 1.5, "discount": 0.1}]
from typing import Any, NotRequired, Optional, TypedDict
class Product(TypedDict):
id: int
sku: str
price: float
note: NotRequired[Optional[Any]]
discount: NotRequired[float]
price is 2 in one item and 1.5 in the other; PEP 484 lets an int stand in for a float, so the field is float. At runtime Product.required_keys is {'id', 'sku', 'price'} and optional_keys is {'note', 'discount'} (checked with Python 3.12). A type checker then accepts a product without discount and rejects one without sku (mypy 2.3.1: Missing key “sku” for TypedDict “Product”).
Limits
nullbecomesOptional[Any]; replaceAnywith the real type.- Keys that are not valid Python identifiers (for example
user-idor keywords such asclass) need renaming, plusField(alias="user-id")in Pydantic. - Dates stay
str; Pydantic converts ISO 8601 strings if you change the type todatetime. - Arrays of primitives at the root generate no class.
Empty arrays and sample coverage
An empty array gives the generator no evidence about its element type, so {"tags": []} produces tags: List[Any]. Include another object with {"tags": ["admin"]} in the same input array and the merged field becomes List[str]. The generator uses the samples you provide. It cannot infer a field that appears in none of them. Include representative objects with missing keys and null values before copying the classes.
FAQ
What does this tool generate?
It generates Python class definitions from JSON. Choose between standard @dataclass (stdlib), Pydantic v2 BaseModel, or TypedDict. Each nested object becomes its own named class.
What output modes are supported?
Three modes: @dataclass (Python stdlib, default), Pydantic v2 BaseModel, and TypedDict (Python 3.8+; NotRequired needs 3.11+ or typing_extensions).
How are JSON types mapped to Python types?
string → str, integer → int, float → float, boolean → bool, null → Optional[Any], array → List[T], nested object → separate class.
When are fields marked as Optional?
A field is marked Optional[T] = None when its value is null in the JSON sample, or when it is missing in some objects of a merged array.
How are nested objects handled?
Each nested object is extracted into a separate class named after the field key in PascalCase. Child classes are always defined before the parent class so the output is immediately usable.
Is my data sent to a server?
No. The entire conversion runs in your browser. No data leaves your machine.