datamodel-code-generator: Python Data Model Generator
datamodel-code-generator is a command-line tool that turns OpenAPI, JSON Schema, GraphQL, Avro, Protobuf, and raw JSON/YAML/CSV into Pydantic v2, dataclass, TypedDict, or msgspec.Struct code. Reach for it when your models come from a schema you don't want to hand-write twice, especially inside a CI pipeline. Skip it if your schema set is small enough that hand-writing a few Pydantic classes takes less time than learning the preset and flag system.
Generate Python Models from Schemas
datamodel-code-generator is a Python code generator that reads a schema file and writes matching Python model classes. It accepts OpenAPI 3, AsyncAPI, JSON Schema, XML Schema, Protocol Buffers, Apache Avro, GraphQL, MCP tool schemas, and raw JSON/YAML/CSV as input, outputting Pydantic v2 BaseModel, Pydantic v2 dataclass, standard dataclasses, TypedDict, or msgspec.Struct code. It ships as the `datamodel-codegen` CLI.
Supported Inputs and Outputs
- ✓Reads OpenAPI 3, AsyncAPI, JSON Schema, XML Schema (XSD), Protocol Buffers/gRPC, Apache Avro, GraphQL, MCP tool schemas, and raw JSON/YAML/CSV/Python-dict data as input.
- ✓Writes Pydantic v2 BaseModel, Pydantic v2 dataclass, standard dataclasses, TypedDict, or msgspec.Struct as output — you pick the target with `--output-model-type`.
- ✓The `--input-model path/to/file.py:ClassName` option allows for the retargeting of a Pydantic, dataclass, or TypedDict class that exists in a separate file, enabling its use with a different output type and thus ensuring you are not restricted to the initial style generated.
- ✓Resolves complex schema constructs — `$ref`, `allOf`, `oneOf`, `anyOf`, enums, and nested types — into working Python type hints.
- ✓Ships named presets, like `standard-py312-20260619` and `practical-py312-20260619`, that pin a maintained set of defaults for a target Python version instead of making you assemble dozens of flags yourself.
- ✓Formats generated code with `black` and `isort` by default, with `--formatters builtin` for faster generation without those dependencies, or with Ruff via `--formatters ruff-check ruff-format`.
Installation Methods
The README's recommended path for standalone CLI use is `uv tool install datamodel-code-generator`. Conda users can run `conda install -c conda-forge datamodel-code-generator`, and projects that want to pin the generator as a dev dependency should use `uv add --dev datamodel-code-generator` instead. Plain `pip install datamodel-code-generator` works too, or run it without adding it to a project via `uv run --with datamodel-code-generator datamodel-codegen --help`. Extras add optional features: `datamodel-code-generator[http]` for resolving remote `$ref`s, `[graphql]` for GraphQL input, and `[protobuf]` for Protocol Buffers input. A Docker image is published as `koxudaxi/datamodel-code-generator` and runs under a non-root `appuser` account, so a bind-mounted output folder needs write access for that user, or you add `--user "$(id -u):$(id -g)"` to the docker run command. Community packages also exist for Debian, Ubuntu, nixpkgs, and openSUSE Tumbleweed, though the README notes availability and versions vary by distribution.
Quick Start with the CLI
The quick-start command from the README is: ```bash datamodel-codegen \ --input schema.json \ --input-file-type jsonschema \ --output-model-type pydantic_v2.BaseModel \ --preset standard-py312-20260619 \ --output model.py ``` That preset name encodes the target Python version — `py312` means Python 3.12 — and hands you a maintained bundle of default flags instead of making you assemble them yourself. Point `--input` at any supported schema file, set `--input-file-type` to match it, and pick your target with `--output-model-type` (`pydantic_v2.BaseModel`, `dataclass`, `typeddict`, or `msgspec.Struct`, among others). For a repeatable setup, the same options can live in a `[tool.datamodel-codegen]` table inside `pyproject.toml`, after which running bare `datamodel-codegen` picks them up automatically. Generated code is formatted with `black` and `isort` by default; add `--formatters builtin` to skip those dependencies and generate faster, or `--formatters ruff-check ruff-format` if you'd rather use Ruff.
Where datamodel-code-generator is Used
- •The README's dependents list credits openai/codex with using datamodel-code-generator to generate the public Python SDK types for its protocol schemas.
- •modelcontextprotocol/python-sdk generates its MCP protocol models from vendored JSON Schemas with it, per the same list.
- •apache/airflow drives an OpenAPI-to-datamodel step for airflow-ctl and task-sdk through a pyproject-based codegen config, according to the README.
- •PostHog/posthog turns JSON Schema into Pydantic models with it, and DataDog/integrations-core uses it to build its integration config models.
- •Test and evaluation suites lean on it too — the README lists it as a test dependency for vllm-project/vllm's MiniCPM3 tests and an evaluation dependency for browser-use/browser-use.
Strengths
- ✓One tool covers an unusually wide spread of input formats — OpenAPI, AsyncAPI, JSON Schema, XML Schema, Protocol Buffers, Avro, GraphQL, MCP tool schemas, and raw JSON/YAML/CSV — instead of needing a different generator per format.
- ✓`--input-model path/to/file.py:ClassName` retargets an existing Pydantic, dataclass, or TypedDict class to a different output style without hand-rewriting it.
- ✓Named presets like `standard-py312-20260619` and `practical-py312-20260619` bundle sane defaults for a target Python version, so you don't have to research dozens of flags before a first run.
- ✓The dependents list in the README shows it running in real production codebases — openai/codex, apache/airflow, PostHog/posthog — not just toy demos.
- ✓MIT license, so there's no copyleft term to negotiate before vendoring the generator into a commercial build.
Considerations and Known Behaviors
- △Generated code is formatted with `black` and `isort` by default today, but the README says a future release will make that opt-in and switch the default formatter to `builtin` — pin your formatter choice explicitly if you don't want that shift to surprise a pipeline.
- △Remote `$ref` resolution isn't in the base install; you need the `[http]` extra, and the experimental `httpx2` backend requires installing that extra separately and isn't bundled in `[all]`.
- △GraphQL and Protocol Buffers input each need their own extra (`[graphql]`, `[protobuf]`) — you can't just point it at a `.proto` file out of the box.
- △Custom output templates aren't exhaustively checked by the `--formatters builtin` validator, so unusual template output may need a manual bug report rather than working automatically.
- △The CI/CD example in the README leaves the GitHub Action version as a placeholder (`@vX.Y.Z`) — you have to look up and pin a real released tag yourself.
Related Projects in the Ecosystem
Common Questions
datamodel-code-generator reads OpenAPI 3, AsyncAPI, JSON Schema, XML Schema, Protocol Buffers, Apache Avro, GraphQL, MCP tool schemas, and raw JSON, YAML, or CSV data, plus existing Python Pydantic, dataclass, or TypedDict classes via `--input-model`.
datamodel-code-generator can output Pydantic v2 BaseModel, Pydantic v2 dataclass, standard dataclasses, TypedDict, or msgspec.Struct classes, selected with the `--output-model-type` flag.
The README recommends `uv tool install datamodel-code-generator` for standalone CLI use, `conda install -c conda-forge datamodel-code-generator` for Conda, or plain `pip install datamodel-code-generator`; a Docker image is also published.
datamodel-code-generator is built with CI/CD in mind: the README documents a CI/CD Integration guide covering GitHub Actions and pre-commit hooks, plus a GitHub Action referenced as `koxudaxi/[email protected]` for regenerating and validating models in a pipeline.
The README states playground generation runs locally in your browser via Pyodide, so your schema and options are never sent to a backend; shared reproduction URLs encode state in a URL fragment that browsers don't transmit to servers, though the full URL can still end up saved in your browser history or wherever you share it.
datamodel-code-generator is released under the MIT License, per the LICENSE file referenced in the README.
The problem it solves
Teams that consume or publish JSON Schema, OpenAPI, or GraphQL specs end up hand-writing the matching Pydantic or dataclass code anyway, and that hand-written copy drifts from the schema the moment either side changes. datamodel-code-generator closes that gap by regenerating the Python side directly from the schema file, so a schema update and a model update stay one command apart instead of two manual edits that can quietly disagree.
Who should try it — and who should skip
Reach for datamodel-code-generator if you already have (or consume) an OpenAPI, JSON Schema, GraphQL, Avro, or Protobuf definition and want the matching Pydantic v2, dataclass, TypedDict, or msgspec.Struct code kept in sync with it automatically — particularly if that sync needs to run inside CI. Skip it if you don't have a formal schema to generate from, or if your model set is small enough that writing five Pydantic classes by hand is genuinely less work than learning the preset and flag system first.
