HomeJSON ConvertersJSON to Python

JSON to Python

Convert JSON to typed Python dataclasses, Pydantic models, or plain dictionaries instantly. Features PEP 8 snake_case key conversions, Python 3.10+ native typings, and dataclass custom serializers.

Convert JSON to typed Python dataclasses, Pydantic models, or plain dictionaries instantly. Features PEP 8 snake_case key conversions, Python 3.10+ native typings, and dataclass custom serializers.

This tool is designed to provide a seamless experience for developers by handling complex operations directly in your browser with maximum speed and security.

100% Private
Instant Results
Customizable
Offline Ready
Dev-Friendly
Easy Export

A JSON to Python converter reads a JSON object or array and generates Python code that represents the same data structure — either as a Python dictionary literal for simple use cases, or as a typed dataclass or Pydantic model for production code that needs type safety, editor autocompletion, and runtime validation.

Python's json.loads() function has always been able to parse JSON. The result is a plain dict — and for a quick script, that is perfectly adequate. The problem with plain dicts at scale is that they have no type information attached. When you access data["user"]["profile"]["timezone"], your editor has no idea what type timezone is, cannot autocomplete it, cannot warn you if you misspell the key, and cannot tell you when a refactor breaks that access pattern. Every key access is a runtime operation on an untyped dict, and bugs introduced by API changes or schema drift are invisible until they crash in production.

Python dataclasses, introduced in Python 3.7, solve this by giving your JSON data a proper class representation with typed fields. A dataclass generated from a JSON payload is a class you can import, instantiate, and pass around your codebase. Your editor knows the type of every field. Mypy can statically analyse your entire call chain. A schema change in the upstream API that renames a field becomes a type error caught at development time rather than a KeyError caught at runtime.

Pydantic takes this further. Where dataclasses are a Python standard library feature with no runtime validation, Pydantic models validate field types at instantiation time and raise clear, structured errors when the incoming JSON does not match the expected schema. They also support field aliases, which is the mechanism you need when your JSON uses camelCase keys (firstName, isActive, joinedAt) but your Python code follows PEP 8 snake_case conventions (first_name, is_active, joined_at). A Pydantic model generated from your JSON payload handles this aliasing automatically — you deserialise with the camelCase alias, work with the snake_case field name throughout your Python code, and serialise back to camelCase for the API if needed.

This tool generates both output styles. For quick scripts or data inspection work, the plain dict output gives you a Python literal you can paste and use immediately. For application code, the dataclass or Pydantic model output gives you a type-safe representation that integrates cleanly with your existing Python toolchain.

Read the Full Guide

This tool takes a JSON object or array and generates Python code representing the same data structure. Depending on the output mode you select, it produces one of three things: a plain Python dictionary literal, a Python dataclass with type annotations, or a Pydantic BaseModel with field definitions and aliases. For plain dict output, the tool produces a Python dict literal that mirrors your JSON structure exactly. Nested objects become nested dicts. Arrays become Python lists. JSON strings become Python strings. JSON numbers become Python int or float. JSON booleans become Python True or False (with the capitalisation difference from JSON's true and false handled automatically). JSON null becomes Python None. The result is a Python expression you can assign to a variable and use immediately. For dataclass output, the tool generates a @dataclass class for every nested object level in your JSON. Each field is annotated with its inferred Python type: str for string fields, int for integer fields, float for decimal fields, bool for boolean fields, None-able fields as Optional[str], Optional[int], and so on. Lists of primitives become List[str], List[int], or List[Any] depending on the element type consistency across your sample. Nested objects generate their own dataclass definition, and the parent class references them by name. The output imports dataclasses.dataclass and dataclasses.field, plus typing.Optional, typing.List, and typing.Any as needed. For JSON keys that use camelCase — the JavaScript convention that is standard in REST API responses — the generator produces snake_case field names following Python's PEP 8 naming convention, with a field(default=...) alias that maps the camelCase JSON key to the snake_case Python attribute. This means you deserialise from camelCase JSON using the alias and work with snake_case in all your Python code. For Pydantic output, the generated class inherits from pydantic.BaseModel rather than using the @dataclass decorator. Field types are the same, but the model gains Pydantic's runtime validation, .model_validate() for deserialisation from a dict or JSON string, .model_dump() for serialisation back to a dict, and model_config with populate_by_name and alias generator support for camelCase API compatibility. The output is ready to use as a request or response model in a FastAPI application or any Python service that uses Pydantic for data validation.

1. Paste your JSON into the input editor or load one of the interactive templates. If you paste an array, the tool infers the schema from the union of all keys across all objects in the array, so fields that appear in only some records are correctly typed as Optional.

2. Select your output mode: Dataclass for standard @dataclass classes, Pydantic Model for validation models, or Plain Dict for simple key-value structures.

3. Turn on PEP 8 snake_case key conversion if your JSON utilizes camelCase. The engine automatically produces pythonic field names while mapping original keys using metadata aliases.

4. Enable 'Generate Serialization Helper Methods' to add fully recursive .from_dict() and .to_dict() functions to your standard dataclasses, including date, time, and UUID deserialization.

5. Copy the generated Python code or download the script directly.

Every Python developer who works with APIs has written the same code dozens of times. You get a JSON response, you call json.loads(), you start accessing keys with data["user"]["profile"]["email"], and everything works fine until the API changes a field name, adds a nested level, or starts returning null for a field you assumed was always present. The bug is silent until it hits production. The pattern I have seen most often in Python codebases that started without typed models is what I call the dict chain: deeply nested key access spread across dozens of files, no central definition of what the JSON structure looks like, and no way to know which parts of the codebase break when the API schema changes. Refactoring out of this pattern after the fact is painful. Starting with a typed model from the first API call costs almost nothing — especially when a tool generates it for you. Python dataclasses are the right tool for local or script-level work where you want type checking and editor support but do not need runtime validation. They are zero-dependency (standard library since Python 3.7), lightweight, and integrate directly with mypy for static analysis. For a CLI tool, a data pipeline script, or a batch processing job that consumes a JSON API, a dataclass representation of the response structure is strictly better than a plain dict — same performance, dramatically better maintainability. Pydantic is the right tool for application-level work, particularly in FastAPI and anywhere you are accepting JSON input from external sources. Pydantic validates field types at instantiation time and raises ValidationError with clear field-level messages when the incoming data does not match. This is the difference between a cryptic KeyError at an unexpected place in your application and a structured error at the boundary where the data enters your system. FastAPI uses Pydantic models as its entire request and response schema system — if you are writing FastAPI endpoints, you are already using Pydantic whether you know it or not. The camelCase to snake_case conversion is one of those small things that saves a disproportionate amount of friction. REST APIs almost universally use camelCase because JSON comes from JavaScript. Python code almost universally uses snake_case because PEP 8 requires it. Without aliasing, you either violate PEP 8 by using camelCase Python attributes, or you write manual mapping code in every deserialisation call. A generated model with proper aliases handles this at the class definition level — once, correctly, with no repeated mapping logic throughout your codebase. The browser-based, no-install design has practical value beyond convenience. When you are pair-programming, reviewing a PR, or debugging an API response on a shared screen, reaching for this tool is faster than opening a Python REPL, importing json and dataclasses, and manually writing out type annotations. Paste, generate, review the structure — the whole thing takes fifteen seconds.

Full type annotations — str

int

float

bool

Optional

List

Dict

Any inferred from your JSON values

snake_case field names generated from camelCase JSON keys with field() aliases for correct deserialisation

Nested JSON objects generate separate named dataclass or Pydantic model classes automatically

Optional typing applied to null JSON fields and fields absent from some array elements

Three output modes — plain dict

dataclass

and Pydantic BaseModel — for different use cases

Pydantic output is FastAPI-ready with Field aliases and model_config for camelCase API compatibility

Runs entirely in your browser — zero data transmitted to any server

Free with no account

no rate limits

no install required

Generating typed Python dataclasses from a REST API response for type-safe consumption in application code

Creating Pydantic request and response models for FastAPI endpoints from a JSON API specification

Converting a third-party webhook payload JSON into a typed Python model for processing in a Django or Flask service

Building typed data models for a Python data pipeline that consumes JSON from Kafka or an event stream

Generating Python dict fixtures from JSON test data for use in pytest unit tests

Scaffolding Python model classes when integrating a new external API for the first time

Creating typed Python representations of JSON configuration files for a CLI tool or automation script

Prototyping a Python data model from an API response before writing full Pydantic schema validation

Example Input

{
  "id": 1,
  "name": "Priya Singh",
  "email": "priya@techcorp.io",
  "role": "Principal Engineer",
  "yearsExperience": 15,
  "isActive": true,
  "joinedAt": "2019-03-12",
  "skills": ["Python", "PostgreSQL", "Go", "System Design"],
  "profile": {
    "bio": "15 years in distributed systems and data infrastructure.",
    "timezone": "Asia/Kolkata",
    "githubHandle": "priyasingh-eng",
    "reportsTo": null
  }
}

Example Output

from dataclasses import dataclass, field
from typing import Optional, List, Any


@dataclass
class Profile:
    bio: str
    timezone: str
    github_handle: str = field(metadata={"alias": "githubHandle"})
    reports_to: Optional[Any] = field(default=None, metadata={"alias": "reportsTo"})


@dataclass
class User:
    id: int
    name: str
    email: str
    role: str
    years_experience: int = field(metadata={"alias": "yearsExperience"})
    is_active: bool = field(metadata={"alias": "isActive"})
    joined_at: str = field(metadata={"alias": "joinedAt"})
    skills: List[str]
    profile: Profile

TypeError: __init__() got an unexpected keyword argument 'firstName' when calling MyClass(**data)

Fix: Your JSON uses camelCase keys but your dataclass uses snake_case field names. Python dataclasses do not support key aliases natively — **data unpacking uses the dict keys as argument names directly. Either rename your dataclass fields to match the camelCase JSON keys exactly (violating PEP 8 but functional), use a mapping step to convert keys before unpacking, use the dacite library which supports field renaming, or switch to Pydantic which has native alias support via Field(alias='firstName').

pydantic.ValidationError: field required — Pydantic raises an error on a field that exists in the model but is missing from the JSON

Fix: The field is defined without a default value in the generated Pydantic model, meaning Pydantic treats it as required. If the field is genuinely optional in your data, change its type from str to Optional[str] and add a default: field_name: Optional[str] = None. If the field should always be present and the API is sending malformed data by omitting it, the ValidationError is correct — investigate why the upstream response is missing the field.

AttributeError: 'NoneType' object has no attribute 'upper' (or similar) — runtime error accessing a method on an Optional field

Fix: A field typed as Optional[str] is None at runtime and you are calling a string method on it without a None check. Add a guard: if obj.field_name is not None: before accessing the field, or use the walrus operator: if value := obj.field_name: ... . In Pydantic you can also use a validator to provide a default non-None value for fields that should never actually be None in practice.

mypy error: Incompatible types in assignment — int vs float on a numeric field

Fix: The generator typed the field as int because your sample value was an integer, but your production code is assigning a float to it. Change the type annotation from int to float (Python's float covers all decimal numbers) or Union[int, float] if the field legitimately holds both. In Python, int is not a subtype of float for mypy purposes — you cannot assign 3.14 to a variable annotated as int without a type error.

Pydantic model does not deserialise camelCase JSON correctly — fields come back as None

Fix: Pydantic models with snake_case field names and camelCase Field(alias=...) definitions require either model_config = ConfigDict(populate_by_name=True) or using model_validate() with the by_alias=False parameter. If you call MyModel(**data) with camelCase keys and your model has snake_case fields, Pydantic will not find matching fields and they will default to None. Use MyModel.model_validate(data) which respects alias definitions correctly.

Trusting the inferred type for fields that can hold multiple types in production — the generator infers type from your sample JSON. If your sample has yearsExperience: 15 (an integer), the field is typed as int. But if your production API sometimes returns yearsExperience: 15.5 for contractors paid at a fractional rate, your dataclass will silently accept incorrect types at runtime (dataclasses do not validate types) or raise a ValidationError in Pydantic. Review every numeric field and decide whether it should be int, float, or Union[int, float] based on your full data contract, not just your sample.

Forgetting to handle the camelCase alias when deserialising with dataclasses — Python dataclasses do not have built-in alias support the way Pydantic does. The generated field() metadata with alias is a pattern for documentation and manual mapping, not automatic deserialisation. If you call MyClass(**json.loads(response.text)) on a JSON payload with camelCase keys and your dataclass uses snake_case field names, Python will raise a TypeError for unexpected keyword arguments. Use dacite, marshmallow, or a manual mapping layer to handle the key transformation, or switch to Pydantic which handles aliases natively.

Using Optional[str] for a field that is currently null but will always have a value once your data is populated — Optional means the field can be None at runtime, which propagates through your codebase. If you annotate a field as Optional[str] but then access .upper() on it without a None check, you get an AttributeError when it is actually None. Only use Optional for fields that are genuinely optional in your data model, not just absent in your test sample.

Not versioning your generated models when the upstream API changes — a generated dataclass or Pydantic model is a contract between your code and the external API. When the API adds a new required field, your Pydantic model will raise a ValidationError for every response that includes the new field if you have not updated the model. When the API removes a field, any code that accesses that field on the model will fail. Treat generated models as code you own, commit them to source control, and update them when the upstream API changes.

Using a single-object JSON sample when the API can return varying structures — if you generate a model from one response, fields that only appear in some responses will be missing from your model entirely. Generate from a diverse sample or from the API's official JSON Schema if one is available. At minimum, test your generated model against several real API responses before using it in production.

What is the benefit of Python 3.10+ modern typings?

In Python 3.10+, union types can be written using the pipe operator (str | None) instead of Union/Optional from typing, and lists can be annotated as list[str] instead of List[str], removing the need for typing imports and making your code cleaner.

How does it handle camelCase JSON keys in Python snake_case code?

When snake_case conversion is enabled, the generator converts every camelCase JSON key to its snake_case equivalent — yearsExperience becomes years_experience, isActive becomes is_active, joinedAt becomes joined_at. For dataclass output, it adds field() metadata with the original camelCase key as an alias for documentation and manual mapping. For Pydantic output, it generates Field(alias='yearsExperience') on each converted field and adds model_config = ConfigDict(populate_by_name=True) to the model class, enabling Pydantic to deserialise from camelCase JSON automatically using model_validate().

Does it support custom serialization mapping helper methods?

Yes! When standard Dataclasses are selected, you can enable custom helper method generation. This adds robust, recursively nested from_dict() classmethods and to_dict() methods to map camelCase aliases, date/dateTime ISO strings, and standard collections perfectly without third-party dependencies.

Is Pydantic v2 supported?

Yes! The tool supports both Pydantic V2 and V1. When V2 is selected, it configures model_config using ConfigDict, populate_by_name, and frozen options appropriately.

What Python type is used for null JSON values?

JSON null values and fields that are absent from some records in an array are typed as Optional[T] (or T | None in Python 3.10+) in the generated output, where T is the inferred type from non-null occurrences of the same field. A field that is null in your entire sample is typed as Optional[Any] with a default of None. In Python, Optional[str] is equivalent to Union[str, None] — it means the field can hold a string or None.

Is the output compatible with FastAPI?

Yes, when you select Pydantic output mode. FastAPI uses Pydantic models for all request body parsing, response serialisation, and automatic OpenAPI schema generation. A Pydantic BaseModel generated by this tool can be used directly as a FastAPI request body type or response_model.

Is my JSON data sent to any server?

No. The entire conversion runs in your browser using JavaScript. Your JSON is never transmitted to any server, never logged, and never stored anywhere outside your local browser tab.