DEV Community

Cover image for Generate Pydantic v1/v2 Models from JSON in Seconds (and What to Fix Afterward)
Muhammad Iqbal
Muhammad Iqbal

Posted on Originally published at aabitech.com

Generate Pydantic v1/v2 Models from JSON in Seconds (and What to Fix Afterward)

Hand-writing Pydantic models from a large JSON payload is mechanical work: map types, nest classes, repeat. I've been using a free JSON to Pydantic Converter from AabiTech to skip that step. Here's what it does and where you still need to think.

What it does

Paste JSON (or upload a file, up to 5 MB) and get Python model code back.

  • Nested objects become separate models, and arrays of objects become list[Model]
  • Pydantic v2 or v1 compatibility mode
  • Configurable root model name
  • 2, 4, or 8 space indentation
  • Copy to clipboard or download as .py
  • Runs client-side; the page states your JSON is processed in the browser and generated code is never executed

No signup required.

Example

Input:

{
  "name": "Ayesha",
  "age": 25,
  "active": true
}
Enter fullscreen mode Exit fullscreen mode

Output:

from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int
    active: bool
Enter fullscreen mode Exit fullscreen mode

With nested payloads, you get one class per object, referenced from the parent. That's where it saves the most time.

v1 vs v2: pick the right mode

The two versions differ enough that wrong-version output will bite you:

Pydantic v1 Pydantic v2
Parse a dict Model.parse_obj(d) Model.model_validate(d)
Serialize m.dict() m.model_dump()
Config class Config: model_config = ConfigDict(...)

Select the mode matching your installed version, then verify imports and config anyway.

What a single sample can't tell you

Generated models are inferred from one example, so review these before shipping:

1. Optional vs nullable. These are different things.

a: str | None            # required, but may be None
b: str | None = None     # may be omitted, may be None
Enter fullscreen mode Exit fullscreen mode

A sample with "b": null doesn't tell you whether b can be absent. Check more records.

2. Mixed types. If a field is int in some records and str in others, you need a union or a validator:

id: int | str
Enter fullscreen mode Exit fullscreen mode

3. Key naming. firstName, user-id, or keys with spaces need Python-safe attribute names plus aliases:

from pydantic import BaseModel, Field

class User(BaseModel):
    first_name: str = Field(alias="firstName")
Enter fullscreen mode Exit fullscreen mode

Check alias and serialization settings (by_alias=True on dump) before wiring this to an external API.

4. Empty arrays. [] gives no item type to infer from. Fill it in manually.

5. Constraints. No sample will tell you about min_length, regex patterns, enums, or ranges. Add them yourself.

Suggested workflow

  1. Validate your JSON first (the site also has a JSON Formatter)
  2. Use a representative sample, ideally the most complete record you have
  3. Generate with the right Pydantic version
  4. Fix optionals, unions, and aliases
  5. Add validators and constraints
  6. Test against both valid and invalid payloads

Plugged into FastAPI, the result gives you request validation and OpenAPI docs almost immediately:

@app.post("/users")
async def create_user(user: User):
    return user
Enter fullscreen mode Exit fullscreen mode

Privacy note

Even though processing happens in the browser, keep tokens, passwords, and real customer data out of sample payloads. Good habit for any online tool.

Try it

aabitech.com/tools/json-to-pydantic-converter

Treat the output as a solid first draft, not a finished schema. How do you handle messy third-party API responses? Share your approach in the comments.

Top comments (0)