Sheet 03 Python classes
JSON to Python
Paste JSON samples and get dataclasses, Pydantic v2 models or TypedDicts, with snake_case attributes that still map to your original keys.
from dataclasses import dataclass
from typing import Any
@dataclass
class Address:
street: str
city: str
zip_code: str
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "Address":
return cls(
street=data["street"],
city=data["city"],
zip_code=data["zipCode"],
)
@dataclass
class Project:
name: str
year: int
role: str | None = None
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "Project":
return cls(
name=data["name"],
year=data["year"],
role=data.get("role"),
)
@dataclass
class Root:
user_id: int
user_name: str
is_admin: bool
last_login: str
address: Address
projects: list[Project]
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "Root":
return cls(
user_id=data["userId"],
user_name=data["userName"],
is_admin=data["isAdmin"],
last_login=data["lastLogin"],
address=Address.from_dict(data["address"]),
projects=[Project.from_dict(v0) for v0 in data["projects"]],
)
1 sample · 3 classes
How it works
Each sample is read as a value of the root class. Classes are written in dependency order, so nested classes come first and every annotation resolves.
- dataclasses
- Fields without defaults come first, then optional ones with
= None.from_dict()maps the original keys to the snake_case attributes and builds nested objects, lists and dicts of them. - Pydantic v2
- Renamed attributes get
Field(alias="firstName")and the model setspopulate_by_name=True, so both spellings validate. - TypedDict
- Keys must match the JSON exactly, so names are never changed; keys that are not identifiers use the functional
TypedDict("Root", {...})form, and optional keys areNotRequired. - Syntax
- 3.11+ writes
list[str]andstr | None; 3.8+ usesList,Optionaland typing_extensions.
Questions
What happens to keys like class or first-name?
Keywords get a trailing underscore (class_), other names are converted to snake_case (first_name), and the original key is kept in an alias or in from_dict(). Names that would shadow str, list or self get an underscore too.
Does Pydantic parse nested objects for me?
Yes. Root.model_validate(data) builds the nested models from plain dicts, using the aliases. With dataclasses, Root.from_dict(json.loads(text)) does the same job.
Is my JSON uploaded?
No. The code is generated by JavaScript running in this tab, and nothing you paste leaves it. The site counts page views with Cloudflare Web Analytics, which sets no cookies and never receives what you paste.