Seed fractional prices
If a money-like field only ever appears as 18, the emitter picks int. Add one fractional example (for example 18.5) when the API can return cents-style decimals.
Drop JSON on the left; annotated @dataclass modules show up on the right.
Sample: warehouse inventory with manager, SKU list, null holdReason, lastAudit
Converting posts the sample JSON to /api/convert, which returns Python dataclass source. The request body is not written to a database and is omitted from application logs. A short-lived in-memory cache may retain the result for up to one hour. Remove credentials and PII before you convert.
Start from a live API body, inspect the @dataclass modules, then drop them into your package before wiring json.loads.
Use a FastAPI, Flask, or Django JSON body that matches production. Upload a .json file if that is easier. Broken syntax? Clean it with the JSON validator first.
{
"warehouseId": "WH-42",
"region": "apac",
"manager": {
"name": "Aiko Sato",
"badgeId": 1188,
"onCall": true
},
"skus": [
{ "code": "PLN-01", "units": 40, "unitCost": 12.5, "fragile": false },
{ "code": "GLS-09", "units": 6, "unitCost": 88, "fragile": true }
],
"lastAudit": "2026-10-28T09:15:00Z",
"holdReason": null,
"tags": ["priority", "cold-chain"]
}Root holds top-level fields. Nested objects such as manager become sibling @dataclass types. Arrays of objects typically become List[Skus]-style collections with snake_case attributes.
from dataclasses import dataclass
from typing import List
from datetime import datetime
@dataclass
class Manager:
name: str
badge_id: int
on_call: bool
@dataclass
class Skus:
code: str
units: int
unit_cost: float
fragile: bool
@dataclass
class Root:
warehouse_id: str
region: str
manager: Manager
skus: List[Skus]
last_audit: datetime
hold_reason: None
tags: List[str]Copy or download the .py text, place it under your models package, then construct instances after json.loads (or via dacite / mashumaro).
A quick map from JSON literals to the annotations this converter emits.
| Seen in the sample | Written in the dataclass |
|---|---|
| Text value | str |
| Whole number | int |
| Number with a fraction | float |
| true / false | bool |
| Object value | Nested @dataclass |
| Array of similar objects | List[NestedClass] |
| Array of strings | List[str] |
| ISO-8601 timestamp string | datetime annotation |
| Key absent on some array items | Optional[T] = None |
| Key always null in the sample | Literal None (widen before shipping) |
If a money-like field only ever appears as 18, the emitter picks int. Add one fractional example (for example 18.5) when the API can return cents-style decimals.
Seeing datetime on a field does not parse the string for you. After json.loads, convert ISO text yourself or use a mapping library before instantiating the dataclass.
How identifiers are cleaned up and how sparse array rows become Optional fields.
JSON keys such as warehouseId land as warehouse_id. Hyphenated headers like api-key become api_key.
When a catalog array mixes rows with and without label, that attribute becomes Optional[str] = None so missing values stay explicit.
Modules start with from dataclasses import dataclass. typing and datetime appear only when the sample needs them — no third-party packages.
Reserved words, digits-first keys, hyphens and spaces are folded into legal snake_case fields.
# {"api-key":"k","class":"demo","3dModel":1,"XMLHttp":true,"order id":9}
from dataclasses import dataclass
@dataclass
class Root:
api_key: str
root_class: str
the_3_d_model: int
xml_http: bool
order_id: intShared code / units stay required. Row-specific fragile and label become Optional defaults.
# [{"code":"PLN-01","units":40,"fragile":true},{"code":"GLS-09","units":6},{"code":"BOX-02","units":12,"label":"fragile"}]
from dataclasses import dataclass
from typing import Optional
@dataclass
class RootElement:
code: str
units: int
fragile: Optional[bool] = None
label: Optional[str] = NoneA minimal pattern for mapping camelCase JSON onto snake_case dataclasses.
Build nested Manager / Skus instances, then call asdict when you need a JSON-friendly dict again.
import json
from dataclasses import asdict
from datetime import datetime
# After pasting the generated dataclasses into models.py:
raw = json.loads(payload)
# Lightweight construction when shapes already match:
root = Root(
warehouse_id=raw["warehouseId"],
region=raw["region"],
manager=Manager(**{ "name": raw["manager"]["name"], "badge_id": raw["manager"]["badgeId"], "on_call": raw["manager"]["onCall"] }),
skus=[Skus(code=s["code"], units=s["units"], unit_cost=s["unitCost"], fragile=s["fragile"]) for s in raw["skus"]],
last_audit=datetime.fromisoformat(raw["lastAudit"].replace("Z", "+00:00")),
hold_reason=raw["holdReason"],
tags=list(raw["tags"]),
)
print(root.manager.name, root.last_audit.isoformat())
print(json.dumps(asdict(root), default=str))Situations where the generated module needs a human pass.
just-types mode skips encoder helpers. Add dacite, mashumaro, or hand-written constructors if you want one-liner hydration.
Always-null sample keys can appear as hold_reason: None. Promote them to Optional[str] (or another type) so future non-null values type-check.
Arrays that alternate scalars and objects are a poor fit for a single element class — prefer Any or a custom Union.
Jump to another language target or tidy the sample first.
Prefer Java POJOs, Go structs, TypeScript interfaces, or C# classes when your service is not Python.
Fold the body in the JSON viewer or validate it with the JSON validator.
Emit a schema via the JSON Schema generator instead of code.
Dataclasses, Optional fields, datetime parsing, snake_case keys and privacy
Edit, format, and beautify JSON
Validate, fix, and inspect JSON
Compare, measure, and map JSON
Convert JSON to other formats
Convert other formats to JSON
Convert, format, fix, and minify XML
Generate code and format other languages