datamodel-code-generator
🚀 Generate Python data models from schema definitions in seconds.
📚 Documentation · 🧪 Playground · 💼 Lead maintainer available for work
[!NOTE] Playground privacy: Generation runs locally in your browser with Pyodide. Your schema and options are not sent to a backend. Shared repro URLs encode them in the URL fragment (
#state=...), which browsers do not send to the server; the full URL can still be stored in your browser history or wherever you share it.
✨ What it does
Pick any one of the supported inputs and pick the Python model style you want as output.
--input-model path/to/file.py:ClassName can even retarget an existing Pydantic, dataclass, or TypedDict class defined
in another Python file to a different output type.
- 📄 Converts OpenAPI 3, AsyncAPI, JSON Schema, Apache Avro, XML Schema, Protocol Buffers/gRPC, GraphQL, MCP tool schemas, and raw data (JSON/YAML/CSV) into Python models
- 🐍 Generates from existing Python types (Pydantic, dataclass, TypedDict) via
--input-model - 🎯 Generates Pydantic v2, Pydantic v2 dataclass, dataclasses, TypedDict, or msgspec output
- 🔗 Handles complex schemas:
$ref,allOf,oneOf,anyOf, enums, and nested types - ✅ Produces type-safe, validated code ready for your IDE and type checker
📦 Installation
Recommended for standalone CLI use:
uv tool install datamodel-code-generator
Conda users can install from conda-forge:
conda install -c conda-forge datamodel-code-generator
For projects that should pin the generator version, add it as a development dependency instead:
uv add --dev datamodel-code-generator
[!NOTE] Community-maintained distribution packages are also available from Debian, Ubuntu, nixpkgs, and openSUSE Tumbleweed. Availability and versions vary by distribution.
Other installation methods
pip:
pip install datamodel-code-generator
uv (run without adding to project):
uv run --with datamodel-code-generator datamodel-codegen --help
With stable HTTP support (for resolving remote $ref):
pip install 'datamodel-code-generator[http]'
The http extra is supported and is not deprecated. To require the experimental
HTTPX2 backend instead, install datamodel-code-generator[httpx2] and pass
--http-backend httpx2. The experimental extra is not included in
datamodel-code-generator[all]. See
HTTP backend selection
for automatic and explicit selection behavior.
With GraphQL support:
pip install 'datamodel-code-generator[graphql]'
With Protocol Buffers support:
pip install 'datamodel-code-generator[protobuf]'
Docker:
docker pull koxudaxi/datamodel-code-generator
Published Docker images run as a non-root appuser. When writing generated files
to a bind-mounted directory, make sure the directory is writable by the container
user or pass an explicit Docker user, for example --user "$(id -u):$(id -g)".
🏃 Quick Start
Command
datamodel-codegen \
--input schema.json \
--input-file-type jsonschema \
--output-model-type pydantic_v2.BaseModel \
--preset standard-py312-20260909 \
--output model.py
This quick start uses standard-py312-20260909 as the modern Python 3.12 baseline.
Preset names include the target Python version: py312 means Python 3.12.
See CLI Reference for all options. See Presets,
--preset, --input-file-type, and
--output-model-type for this command.
For more schema-aware output that preserves schema-authored names, reuses models, and embeds generated
documentation, use practical-py312-20260909.
Input (schema.json)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Pet",
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string",
"description": "The pet's name"
},
"species": {
"type": "string",
"enum": ["dog", "cat", "bird", "fish"],
"default": "dog"
},
"age": {
"type": "integer",
"minimum": 0,
"description": "Age in years"
},
"vaccinated": {
"type": "boolean",
"default": false
}
}
}
Output (model.py)
# generated by datamodel-codegen:
# filename: schema.json
from __future__ import annotations
from enum import StrEnum
from typing import Annotated
from pydantic import BaseModel, ConfigDict, Field
class Species(StrEnum):
dog = 'dog'
cat = 'cat'
bird = 'bird'
fish = 'fish'
class Pet(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
name: Annotated[str, Field(description="The pet's name")]
species: Species = Species.dog
age: Annotated[int | None, Field(description='Age in years', ge=0)] = None
vaccinated: bool = False
Choose a formatter
Choose a formatter to match your project and generation priorities:
- Projects using Ruff: use
--formatters ruff-check ruff-formatto keep generated code consistent with the project's formatting and lint policy. Install it withpip install 'datamodel-code-generator[ruff]'. - No Ruff, Black, or isort, or generation speed is the priority: use
--formatters builtinto avoid running external formatters on standard generated model modules. - Projects using Black/isort: keep
--formatters black isortto preserve the project's formatting and existing generated output.
The current default remains Black/isort, which are still required dependencies. Omitting formatter options continues
normal generation. The future builtin default is intended to reduce required installation dependencies and version
constraints; Ruff will still be recommended for projects that use Ruff. Formatters are never selected automatically
based on installed packages or Ruff configuration. The new [black] and [isort] extras prepare for later
optional installation; their ranges and environment markers match the current required dependencies.
Selecting only a formatter preserves your other generation settings; a preset also supplies model-generation options.
Explicit formatter selection does not pin formatter v