JSON to Python Dataclass & Pydantic Generator

Generate Python dataclasses, Pydantic BaseModel, or TypedDict from JSON data with type inference and snake_case conversion.

What is JSON to Python Dataclass & Pydantic Generator?

Python 3.7+ dataclasses and Pydantic v2 BaseModel are the two dominant ways to model structured data from JSON APIs. Both let you annotate field types and get automatic __init__, __repr__, and comparison methods — but they have very different philosophies. Dataclasses are lightweight and built into Python's standard library: they provide no validation and no JSON parsing. You need json.loads() + dacite or manual construction. Pydantic v2, by contrast, validates types on assignment, coerces values automatically (e.g. turning an int into a str if that's the annotated type), and provides model.model_dump() and model.model_dump_json() for round-trip serialization. TypedDict is a third option: it produces a plain dictionary at runtime with no class overhead, but gives type checkers (mypy, pyright) the ability to validate key access. It is the right choice for lightweight contracts between functions that pass dicts around. This generator supports all three formats. It infers types from JSON values, converts camelCase to snake_case, adds Field(alias=...) for Pydantic to bridge the naming difference, and generates nested class ordering that Python requires (child classes must be defined before any class that references them).

How to Use

  1. Select your output format — "Pydantic" for FastAPI/data validation, "dataclass" for lightweight standard-library usage, "TypedDict" for typed dict contracts
  2. Choose "Modern (3.10+)" syntax for built-in generics (list[str], str | None) or "Legacy (typing)" for Python 3.7–3.9 compatibility with typing.List[str] and Optional[str]
  3. Enable "snake_case" to convert camelCase JSON keys to Pythonic snake_case property names — Pydantic automatically adds Field(alias="originalKey") for correct JSON parsing
  4. Enable "Detect dates" to map ISO-8601 strings to datetime.datetime or datetime.date instead of str
  5. Enable "Optional nulls" to mark null-valued fields as Optional[T] (legacy) or T | None (modern)
  6. Paste your JSON and click "Generate Python Code" — copy the output into your .py file

Why Use This Tool?

Covers all three modern Python modeling approaches: dataclass, Pydantic BaseModel, TypedDict
Pydantic output uses model_config = ConfigDict(populate_by_name=True) so you can construct the model with either the alias or the Python field name
Converts camelCase JSON keys to Pythonic snake_case with Field(alias=...) bridging — no runtime key errors
Generates children-first class ordering, which Python requires (unlike Java/TypeScript where forward references are allowed)
Supports both modern Python 3.10+ syntax and legacy typing module syntax for teams on older Python versions
Runs entirely in the browser — your API response data never leaves your device

Tips & Best Practices

  • For FastAPI, Pydantic is the natural choice — FastAPI's request body parsing and response_model parameter work directly with BaseModel subclasses, giving you automatic validation and OpenAPI documentation
  • Dataclasses do NOT validate types at runtime — if the JSON has "age": "thirty" and your dataclass has age: int, it will not raise an error, it will just store the string. Use Pydantic if you need runtime type safety
  • When using snake_case conversion with Pydantic, remember to set model_config = ConfigDict(populate_by_name=True) so you can pass either the snake_case name or the original alias when constructing the model
  • TypedDict is best used as a type hint for function parameters, not as a base class for runtime instances — mypy will catch wrong key types, but nothing prevents a runtime dict from having wrong values
  • For deeply nested responses (3+ levels), the generated class chain becomes long — consider flattening the response on the API side or using @dataclass(frozen=True) for immutable models

Frequently Asked Questions

Should I use dataclass, Pydantic, or TypedDict?

Use Pydantic BaseModel when: building FastAPI endpoints, you need runtime type validation, or you need .model_dump() / .model_dump_json() for serialization. Use dataclass when: you want no external dependencies, the data is purely internal (never serialized to JSON), and performance matters. Use TypedDict when: you are typing existing code that passes plain dicts around and cannot change to class instances, or you are writing a stub for an external API response.

What is the complete JSON type → Python type mapping?

JSON string → str (or datetime.datetime/datetime.date with date detection). JSON integer → int. JSON float → float. JSON boolean → bool. JSON null → Optional[T] (legacy) or T | None (modern) where T is inferred from context. JSON array → list[T] or List[T] with T from the first element. JSON object → a named class. Heterogeneous arrays → list[Any].

What is the difference between Python 3.10+ and legacy syntax?

Python 3.10 introduced built-in generic syntax and union types: list[str] instead of List[str], str | None instead of Optional[str]. These are more readable and avoid the typing module import. Legacy mode uses from typing import List, Dict, Optional, Union which is required for Python 3.7–3.9. Choose based on your minimum Python version requirement.

How does Pydantic handle camelCase JSON and snake_case Python?

Pydantic v2 uses Field(alias="originalCamelCase") to map the JSON key to the Pythonic snake_case property name. When you use model_config = ConfigDict(populate_by_name=True), both the alias and the Python name work for construction. This means your code uses snake_case everywhere internally, but Pydantic correctly reads and writes the camelCase JSON keys.

When should I NOT use the generator?

Skip it for responses with discriminated unions (a "type" field that controls the shape) — use Pydantic's Discriminated Union feature or Python's typing.Union with a custom validator. Also skip for highly dynamic responses with arbitrary keys — use dict[str, Any] or pydantic.RootModel[dict[str, SomeType]] instead.

Is my data sent to a server?

No. All code generation runs entirely in your browser. Your JSON data never leaves your device.

Real-world Examples

FastAPI request body model from a payment webhook

Stripe and similar payment providers send webhook payloads as camelCase JSON. A Pydantic BaseModel with snake_case fields and Field(alias=...) lets FastAPI parse the webhook body directly with full type validation. The amount field is in cents (integer), and the created field is a Unix timestamp.

Input
{
  "id": "evt_1P9abc",
  "type": "payment_intent.succeeded",
  "livemode": true,
  "created": 1720000000,
  "data": {
    "object": {
      "id": "pi_3Pq",
      "amount": 4999,
      "currency": "usd",
      "status": "succeeded"
    }
  }
}
Output
from pydantic import BaseModel, Field, ConfigDict
from typing import Optional

class Object(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    id: str
    amount: int
    currency: str
    status: str

class Data(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    object: Object

class StripeWebhook(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    id: str
    type: str
    livemode: bool
    created: int
    data: Data

# FastAPI usage:
# @app.post("/webhook")
# async def handle_webhook(payload: StripeWebhook): ...

Dataclass for an internal data pipeline model

When processing data in a pipeline (ETL, analytics), Pydantic's overhead is unnecessary. A plain dataclass is faster and has no dependencies. This example models a row from a data warehouse export where some fields can be None.

Input
{
  "rowId": 10021,
  "sessionId": "sess_aabb",
  "userId": "u_9912",
  "eventType": "page_view",
  "pageUrl": "/pricing",
  "referrer": null,
  "durationMs": 4200,
  "timestamp": "2024-09-01T08:30:00Z"
}
Output
from dataclasses import dataclass
from datetime import datetime
from typing import Optional

@dataclass
class AnalyticsEvent:
    row_id: int
    session_id: str
    user_id: str
    event_type: str
    page_url: str
    referrer: Optional[str]
    duration_ms: int
    timestamp: datetime

Related Tools