# datamodel-code-generator

Source: https://datamodel-code-generator.koxudaxi.dev/

🚀 Generate Python data models from schema definitions in seconds.

<p>
  <a class="md-button md-button--primary" href="getting-started.md">Getting Started</a>
  <a class="md-button md-button--primary" href="playground.md">Open Playground</a>
  <a class="md-button md-button--primary" href="https://koxudaxi.dev/?utm_source=dm_docs&utm_medium=top&utm_campaign=open_to_work">Lead maintainer available for work</a>
</p>

[![PyPI version](https://img.shields.io/pypi/v/datamodel-code-generator.svg)](https://pypi.python.org/pypi/datamodel-code-generator)
[![Conda-forge](https://img.shields.io/conda/v/conda-forge/datamodel-code-generator)](https://anaconda.org/conda-forge/datamodel-code-generator)
[![Downloads](https://api.pepy.tech/badge/datamodel-code-generator/month)](https://pepy.tech/projects/datamodel-code-generator)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/datamodel-code-generator)](https://pypi.python.org/pypi/datamodel-code-generator)
[![codecov](https://codecov.io/gh/datamodel-code-generator/datamodel-code-generator/graph/badge.svg?token=plzSSFb9Li)](https://codecov.io/gh/datamodel-code-generator/datamodel-code-generator)
![license](https://img.shields.io/github/license/datamodel-code-generator/datamodel-code-generator.svg)
[![Pydantic v2](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/pydantic/pydantic/main/docs/badge/v2.json)](https://pydantic.dev)

---

## ✨ What it does

<!-- Source of truth: docs/assets/diagrams/hero.mmd — regenerate with `tox run -e diagrams` -->
![Schema files, raw data, and existing Python models flow through datamodel-code-generator into Python model output types](assets/diagrams/hero-light.svg#only-light){ align=center }
![Schema files, raw data, and existing Python models flow through datamodel-code-generator into Python model output types](assets/diagrams/hero-dark.svg#only-dark){ align=center }

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

---

## 🧪 Try It In Your Browser

Generate models in your browser without installing anything.

!!! 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.

---

## 🚀 Start Here

Install the CLI and generate your first model from [Getting Started](getting-started.md).

!!! note "Default output model"
    When `--output-model-type` is omitted, datamodel-code-generator generates Pydantic v2 BaseModel output
    (`pydantic_v2.BaseModel`). Use `--output-model-type` explicitly when you want dataclasses, TypedDict, or msgspec
    output.

---

## 📥 Choose Your Input

| Input Type | File Types | Example |
|------------|------------|---------|
| 📘 [OpenAPI 3.0/3.1/3.2](openapi.md) | `.yaml`, `.json` | API specifications |
| 📡 [AsyncAPI](asyncapi.md) | `.yaml`, `.json` | Event-driven API specifications |
| 📋 [JSON Schema](jsonschema.md) | `.json`, `.yaml` | Data validation schemas |
| 🪶 [Apache Avro](avro.md) | `.avsc`, `.json` | Avro schemas |
| 🧾 [XML Schema](xmlschema.md) | `.xsd` | XML document schemas |
| 🧩 [Protocol Buffers / gRPC](protobuf.md) | `.proto` | Protobuf messages and service schemas |
| 🔷 [GraphQL](graphql.md) | `.graphql` | GraphQL type definitions |
| 🛠️ [MCP Tool Schemas](mcp-tools.md) | `.json`, `.yaml` | MCP tool input/output schemas |
| 📊 [JSON/YAML/CSV Data](jsondata.md) | `.json`, `.yaml`, `.csv` | Infer schema from data |
| 🐍 [Python Models](python-model.md) | `.py` | Pydantic, dataclass, TypedDict |

---

## ✅ Conformance Signals

CI exercises datamodel-code-generator against pinned external corpora for XML Schema, JSON Schema, AsyncAPI, Apache
Avro, and Protocol Buffers. See the [Conformance Dashboard](conformance.md) for the generated summary of runner scripts,
tox environments, CI jobs, expected corpus counts, and upstream sources.

---

## 📤 Choose Your Output

```bash
# 🆕 Pydantic v2 (recommended for new projects)
datamodel-codegen --output-model-type pydantic_v2.BaseModel ...

# 🏗️ Python dataclasses
datamodel-codegen --output-model-type dataclasses.dataclass ...

# 📝 TypedDict (for type hints without validation)
datamodel-codegen --output-model-type typing.TypedDict ...

# ⚡ msgspec (high-performance serialization)
datamodel-codegen --output-model-type msgspec.Struct ...
```

See [Supported Data Types](supported-data-types.md) for the full list.

---

## 🌐 Generate a FastAPI server or an HTTP client (experimental)

!!! warning "Experimental"
    Server and client generation are experimental since 0.84.0: their options and generated packages may
    change. See [Experimental Features](experimental.md).

From one OpenAPI document, `--generate-server fastapi` writes a FastAPI server package and `--generate-client httpx2`
an HTTPX2 client package, in the same run as the models. The models stay the runtime contract: routes and client
methods take and return the generated models, so the server and the client parse and produce the same classes you already
use. Every generated file is regenerated on each run; keep your own code outside the generated packages.
The commands put everything in one application package, `app`: the generated `app/models.py`, `app/server/`, and
`app/client/`, and your `app/services/`, so no generic top-level name such as `models` or `server` is taken.

This example is the [FastAPI server tutorial](fastapi-server.md#quick-start), and the tests of this project run it as shown.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: index.server-client.openapi -->
<details>
<summary>Input (<code>openapi.yaml</code>)</summary>

<!-- fmt: off -->

```yaml
openapi: 3.1.0
info:
  title: Pets
  version: "1.0"
servers:
  - url: http://localhost:8000
paths:
  /pets:
    get:
      operationId: listPets
      tags: [pets]
      parameters:
        - name: limit
          in: query
          schema: {type: integer, minimum: 1, maximum: 100, default: 20}
      responses:
        "200":
          description: The pets.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pets"}
    post:
      operationId: createPet
      tags: [pets]
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: "#/components/schemas/NewPet"}
      responses:
        "201":
          description: Created.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
  /pets/{petId}:
    get:
      operationId: getPet
      tags: [pets]
      parameters:
        - name: petId
          in: path
          required: true
          schema: {type: integer}
      responses:
        "200":
          description: The pet.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
        "404":
          description: No pet has this ID.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Error"}
components:
  schemas:
    NewPet:
      type: object
      required: [name]
      properties:
        name: {type: string}
        tag: {type: string}
    Pet:
      type: object
      required: [id, name]
      properties:
        id: {type: integer}
        name: {type: string}
        tag: {type: string}
    Pets:
      type: array
      items: {$ref: "#/components/schemas/Pet"}
    Error:
      type: object
      required: [message]
      properties:
        message: {type: string}
```

<!-- fmt: on -->
</details>
<!-- END AUTO-GENERATED DOC EXAMPLE: index.server-client.openapi -->

**Commands**

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: index.server-client.commands -->
<!-- fmt: off -->

```bash
# The application package app, which the generated packages go into
mkdir -p app && touch app/__init__.py

# FastAPI server package in app/server/
datamodel-codegen \
  --input openapi.yaml \
  --input-file-type openapi \
  --openapi-scopes schemas api \
  --output-model-type pydantic_v2.BaseModel \
  --preset standard-py312-20261015 \
  --output app/models.py \
  --generate-server fastapi \
  --server-output app/server \
  --server-package app.server \
  --server-model-package app.models

# HTTPX2 client package in app/client/
datamodel-codegen \
  --input openapi.yaml \
  --input-file-type openapi \
  --openapi-scopes schemas api \
  --output-model-type pydantic_v2.BaseModel \
  --preset standard-py312-20261015 \
  --output app/models.py \
  --generate-client httpx2 \
  --client-output app/client \
  --client-package app.client \
  --client-model-package app.models
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: index.server-client.commands -->

`--openapi-scopes` must include `api`, and both need Python 3.11 or later, to run and as the target version (the preset
sets 3.12); left unset, the run sets them and says how. Each run ends by printing the runtime dependencies of its
package to stderr:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: index.server-client.notice -->
<!-- fmt: off -->

```text
Add the runtime dependencies of app.server to your project:
  uv add "fastapi>=0.141.1" "pydantic>=2.14.0" "typing-extensions>=4.16"
Next steps: implement the stubs in app/services/pets.py, then run the server:
  uv add uvicorn && uv run uvicorn app.server.main:app --reload
or: uv add "fastapi[standard]" && uv run fastapi dev --entrypoint app.server.main:app
See app/server/README.md.
Add the runtime dependencies of app.client to your project:
  uv add "httpx2>=2.13.0" "typing-extensions>=4.16" "pydantic>=2.14.0"
Next steps: call the API with the client:
  from app.client import Client

  with Client(base_url=...) as client:
      client.pets.list_pets(...)
See app/client/README.md.
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: index.server-client.notice -->

**Generated files (trimmed)**

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: index.server-client.tree -->
<!-- fmt: off -->

```text
app/
├── __init__.py
├── models.py
├── server/
├── services/
└── client/
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: index.server-client.tree -->

**Implement the server** in `app/services/pets.py`, which generation wrote once with stubs, by replacing the stubs of the
`Pets` class that subclasses the generated service Protocol; type checkers report a missing method or a mismatched
signature:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: index.server-client.app -->
<!-- fmt: off -->

```python
from app import models
from app.server import HTTPResult
from app.server.services import PetsService


class Pets(PetsService):
    def __init__(self) -> None:
        self.pets: dict[int, models.Pet] = {}

    def list_pets(self, *, limit: int) -> models.Pets:
        return models.Pets(list(self.pets.values())[:limit])

    def create_pet(self, *, body: models.NewPet) -> models.Pet:
        pet = models.Pet(id=len(self.pets) + 1, name=body.name, tag=body.tag)
        self.pets[pet.id] = pet
        return pet

    def get_pet(self, *, pet_id: int) -> models.Pet | HTTPResult[models.Error]:
        if (pet := self.pets.get(pet_id)) is None:
            return HTTPResult(404, models.Error(message=f"Pet {pet_id} not found"))
        return pet
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: index.server-client.app -->

```bash
uv add uvicorn
uv run uvicorn app.server.main:app
```

**Call it with the client** in `call.py`, which sends to the document's server URL by default:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: index.server-client.call -->
<!-- fmt: off -->

```python
from app.client import Client
from app.client.errors import NotFoundError
from app.models import NewPet

with Client() as client:
    pet = client.pets.create_pet(body=NewPet(name="Mimi", tag="cat"))
    print(pet)
    for listed in client.pets.list_pets(limit=10).root:
        print(listed.name)
    try:
        client.pets.get_pet(pet_id=99)
    except NotFoundError as error:
        print(error.status_code, error.body)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: index.server-client.call -->

It prints:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: index.server-client.output -->
<!-- fmt: off -->

```text
id=1 name='Mimi' tag='cat'
Mimi
404 message='Pet 99 not found'
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: index.server-client.output -->

`AsyncClient` offers the same methods as coroutines. See [FastAPI Server Generation](fastapi-server.md) and [Python Client Generation](python-client.md) for every option, the
`pyproject.toml` settings, authentication, and the Python API.

---

## 🍳 Common Recipes

<!-- BEGIN AUTO-GENERATED CLI RECIPE QUICK STARTS -->
### CLI option quick starts

Use these starting points when combining options; each option links to the generated CLI reference for details and examples.

- **Generate a local schema file:** Pin the input type and destination when the source extension is ambiguous or generated output needs a stable path. Options: [`--input`](cli-reference/base-options.md#input), [`--input-file-type`](cli-reference/base-options.md#input-file-type), [`--output`](cli-reference/base-options.md#output).
- **Target Pydantic v2 on modern Python:** Set the output model family and Python/Pydantic compatibility targets together. Options: [`--output-model-type`](cli-reference/model-customization.md#output-model-type), [`--target-python-version`](cli-reference/model-customization.md#target-python-version), [`--target-pydantic-version`](cli-reference/model-customization.md#target-pydantic-version).
- **Use modern Python annotations:** Target a recent Python version and prefer built-in collection and union syntax in generated types. Options: [`--target-python-version`](cli-reference/model-customization.md#target-python-version), [`--use-union-operator`](cli-reference/typing-customization.md#use-union-operator), [`--use-standard-collections`](cli-reference/typing-customization.md#use-standard-collections).
- **Normalize incoming field names:** Convert source names to Python identifiers while preserving explicit alias data for runtime IO. Options: [`--snake-case-field`](cli-reference/field-customization.md#snake-case-field), [`--original-field-name-delimiter`](cli-reference/field-customization.md#original-field-name-delimiter), [`--aliases`](cli-reference/field-customization.md#aliases).
- **Generate operation-focused models:** Limit OpenAPI output to operation shapes and name models from operation IDs and status codes. Options: [`--openapi-scopes`](cli-reference/openapi-only-options.md#openapi-scopes), [`--use-operation-id-as-name`](cli-reference/openapi-only-options.md#use-operation-id-as-name), [`--use-status-code-in-response-name`](cli-reference/openapi-only-options.md#use-status-code-in-response-name).
- **Resolve remote references deliberately:** Enable remote `$ref` loading and configure request metadata, timeouts, or local ref roots. Options: [`--allow-remote-refs`](cli-reference/general-options.md#allow-remote-refs), [`--http-headers`](cli-reference/general-options.md#http-headers), [`--http-timeout`](cli-reference/general-options.md#http-timeout), [`--http-local-ref-path`](cli-reference/general-options.md#http-local-ref-path).

See the [CLI Reference](cli-reference/index.md) for the full option list and category-specific recipes.
<!-- END AUTO-GENERATED CLI RECIPE QUICK STARTS -->

### 🤖 Get CLI Help from LLMs

Generate a prompt to ask LLMs about CLI options:

```bash
datamodel-codegen --generate-prompt "Best options for Pydantic v2?" | claude -p
```

See [LLM Integration](llm-integration.md) for more examples.

### 🌐 Generate from URL {#http-extra-option}

```bash
pip install 'datamodel-code-generator[http]'
datamodel-codegen --url https://example.com/api/openapi.yaml --output model.py
```

The `http` extra is the stable, non-deprecated backend. For the experimental
HTTPX2 alternative, pass `--http-backend httpx2`; see
[HTTP backend selection](faq.md#http-backend-selection).

### ⚙️ Use with pyproject.toml

```toml title="pyproject.toml"
[tool.datamodel-codegen]
input = "schema.yaml"
output = "src/models.py"
output-model-type = "pydantic_v2.BaseModel"
```

Then simply run:

```bash
datamodel-codegen
```

See [pyproject.toml Configuration](pyproject_toml.md) for more options.

### 🔄 CI/CD Integration

Validate generated models in your CI pipeline:

```yaml title=".github/workflows/validate-models.yml"
# Replace vX.Y.Z with a released action version.
- uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
  with:
    input: schemas/api.yaml
    output: src/models/api.py
```

See [CI/CD Integration](ci-cd.md) for more options.

---

## 📚 Next Steps

- 🖥️ **[CLI Reference](cli-reference/index.md)** - All command-line options with examples
- 🧰 **[Presets](presets.md)** - Recommended immutable option bundles
- 🌐 **[FastAPI Server Generation](fastapi-server.md)** - Experimental FastAPI server package from OpenAPI
- 📡 **[Python Client Generation](python-client.md)** - Experimental HTTPX2 client package from OpenAPI
- ⚙️ **[pyproject.toml Configuration](pyproject_toml.md)** - Configure via pyproject.toml
- 🚀 **[One-liner Usage](oneliner.md)** - uvx, pipx, clipboard integration
- 🔄 **[CI/CD Integration](ci-cd.md)** - GitHub Actions and CI validation
- ✅ **[Conformance Dashboard](conformance.md)** - External corpus and CI coverage signals
- 📈 **[Performance Benchmarks](performance-benchmarks.md)** - Release benchmark tables and interactive charts
- 🎨 **[Custom Templates](custom_template.md)** - Customize generated code with Jinja2
- 🖌️ **[Code Formatting](formatting.md)** - Configure black, isort, and ruff
- ❓ **[FAQ](faq.md)** - Common questions and troubleshooting

---

## 💖 Sponsors

<table>
  <tr>
    <td valign="top" align="center">
      <a href="https://github.com/openai">
        <img src="https://avatars.githubusercontent.com/u/14957082?s=200&v=4" alt="OpenAI Logo" style="width: 100px;">
        <p>OpenAI</p>
      </a>
    </td>
  </tr>
</table>

---

## 🏢 Used by

These public examples are grouped by how each project uses datamodel-code-generator.

### Code generation and runtime integration

- [openai/codex](https://github.com/openai/codex) - *[Generate public Python SDK types from protocol schemas](https://github.com/openai/codex/blob/205d37a20f742b0bf8e191622bd07c43f567ea49/sdk/python/scripts/update_sdk_artifacts.py#L558-L590)*
- [modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk) - *[Generate MCP protocol models from vendored JSON Schemas](https://github.com/modelcontextprotocol/python-sdk/blob/main/scripts/gen_surface_types.py)*
- [typesafe-ai/typesafe-sdk-python](https://github.com/typesafe-ai/typesafe-sdk-python) - *[Generate official Jev Python SDK models from the TypeSafe OpenAPI schema](https://github.com/typesafe-ai/typesafe-sdk-python/blob/0ffd094c72ed9445223060b24ffd7a56aa781fb4/src/typesafe_sdk/_schemas/models.py#L1-L2)*
- [modular/modular](https://github.com/modular/modular) - *[Generate MAX Serve KServe schemas from OpenAPI with datamodel-codegen](https://github.com/modular/modular/blob/0735fa29762a5c53d65a0456d0b53eac1472180f/max/python/max/serve/schemas/README.md#L20-L33)*
- [apache/airflow](https://github.com/apache/airflow) - *[Generate OpenAPI datamodels for airflow-ctl and task-sdk via pyproject codegen config](https://github.com/apache/airflow/blob/f1ac27af8b53e7d3ca7ff710c4f4413599bd1535/airflow-ctl/pyproject.toml#L148-L172)*
- [PostHog/posthog](https://github.com/PostHog/posthog) - *[Generate Pydantic models from JSON Schema](https://github.com/PostHog/posthog/blob/master/bin/build-schema-python.sh#L5-L14)*
- [airbytehq/airbyte](https://github.com/airbytehq/airbyte) - *[Generate Python, Java/Kotlin, and Typescript protocol models](https://github.com/airbytehq/airbyte-protocol/tree/main/protocol-models/bin)*
- [open-metadata/OpenMetadata](https://github.com/open-metadata/OpenMetadata) - *[datamodel_generation.py](https://github.com/open-metadata/OpenMetadata/blob/main/scripts/datamodel_generation.py)*
- [topoteretes/cognee](https://github.com/topoteretes/cognee) - *[Runtime generation of graph data models from JSON Schema](https://github.com/topoteretes/cognee/blob/main/cognee/shared/graph_model_utils.py)*
- [e2b-dev/E2B](https://github.com/e2b-dev/E2B) - *[Generate MCP server TypedDict models via Makefile](https://github.com/e2b-dev/E2B/blob/main/packages/python-sdk/Makefile)*
- [DataDog/integrations-core](https://github.com/DataDog/integrations-core) - *[Config models](https://github.com/DataDog/integrations-core/blob/master/docs/developer/meta/config-models.md)*
- [open-telemetry/opentelemetry-python](https://github.com/open-telemetry/opentelemetry-python) - *[Generate SDK configuration dataclasses from JSON Schema](https://github.com/open-telemetry/opentelemetry-python/blob/main/tox.ini)*

### Development, testing, and evaluation

- [browser-use/browser-use](https://github.com/browser-use/browser-use) - *[Evaluation dependency](https://github.com/browser-use/browser-use/blob/de14b9aa31d167696a7ea7185d71876dbd7e6c94/pyproject.toml#L74-L79)*
- [vllm-project/vllm](https://github.com/vllm-project/vllm) - *[Test dependency for MiniCPM3 tests](https://github.com/vllm-project/vllm/blob/46f01a50acd6862806ed67b88176c96c2b161142/requirements/test/cuda.in#L40)*
- [stanfordnlp/dspy](https://github.com/stanfordnlp/dspy) - *[Generate Pydantic models from JSON Schema for reliability tests](https://github.com/stanfordnlp/dspy/blob/main/tests/reliability/generate/utils.py)*

[See all dependents →](https://github.com/datamodel-code-generator/datamodel-code-generator/network/dependents)

---

## 👥 Maintainers

- [Koudai Aono](https://koxudaxi.dev/?utm_source=dm_docs&utm_medium=maintainer_section&utm_campaign=open_to_work) ([@koxudaxi](https://github.com/koxudaxi)) - Lead maintainer
- [Bernát Gábor](https://github.com/gaborbernat) ([@gaborbernat](https://github.com/gaborbernat)) - Maintainer
- [Antonio Spadaro](https://github.com/ilovelinux) ([@ilovelinux](https://github.com/ilovelinux)) - Maintainer

---

# Getting Started

Source: https://datamodel-code-generator.koxudaxi.dev/getting-started/

Install `datamodel-code-generator` and generate your first Pydantic v2 model.

## Installation

=== "uv tool (Recommended for CLI use)"

    ```bash
    uv tool install datamodel-code-generator
    ```

=== "conda"

    ```bash
    conda install -c conda-forge datamodel-code-generator
    ```

=== "uv (project)"

    ```bash
    uv add --dev datamodel-code-generator
    ```

=== "pip"

    ```bash
    pip install datamodel-code-generator
    ```

=== "pipx"

    ```bash
    pipx install datamodel-code-generator
    ```

=== "uvx (one-shot)"

    ```bash
    uvx --from datamodel-code-generator datamodel-codegen --help
    ```

Use `uv tool install` when you want `datamodel-codegen` available as a standalone CLI. Use `uv add --dev` when a project
or CI workflow should pin the generator version in its lockfile.

!!! info "Distribution packages"
    Community-maintained distribution packages are also available from
    [Debian](https://packages.debian.org/search?keywords=datamodel-codegen&searchon=names&suite=all&section=all),
    [Ubuntu](https://packages.ubuntu.com/search?keywords=datamodel-codegen&searchon=names&suite=all&section=all),
    [nixpkgs](https://search.nixos.org/packages?query=datamodel-code-generator), and
    [openSUSE Tumbleweed](https://software.opensuse.org/package/python-datamodel-code-generator).
    Availability and versions vary by distribution.

!!! note "Default output model"
    When `--output-model-type` is omitted, datamodel-code-generator generates Pydantic v2 BaseModel output
    (`pydantic_v2.BaseModel`). You can pass `--output-model-type` explicitly when you want another model family.

---

## Quick Start

<!-- BEGIN AUTO-GENERATED PRESET QUICK START -->
### Command

```bash
datamodel-codegen \
  --input schema.json \
  --input-file-type jsonschema \
  --output-model-type pydantic_v2.BaseModel \
  --preset standard-py312-20261015 \
  --output model.py
```

This quick start uses `standard-py312-20261015` as the modern Python 3.12 baseline.
Preset names include the target Python version: `py312` means Python 3.12.

See [CLI Reference](cli-reference/index.md) for all options. See [Presets](presets.md),
[`--preset`](cli-reference/base-options.md#preset), [`--input-file-type`](cli-reference/base-options.md#input-file-type), and
[`--output-model-type`](cli-reference/model-customization.md#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-20261015`](presets.md#practical-py312-20261015).

<details>
<summary>Input (<code>schema.json</code>)</summary>

```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
    }
  }
}
```

</details>

### Output

<!-- fmt: off -->

```python title="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
```

<!-- fmt: on -->

🎉 That's it! Your schema is now a fully-typed Python model.

### Choose a formatter

Choose a formatter to match your project and generation priorities:

- **Projects using Ruff:** use `--formatters ruff-check ruff-format` to keep generated code consistent with the
  project's formatting and lint policy. Install it with `pip install 'datamodel-code-generator[ruff]'`.
- **No Ruff, Black, or isort, or generation speed is the priority:** use `--formatters builtin` to avoid running
  external formatters on standard generated model modules.
- **Projects using Black/isort:** keep `--formatters black isort` to 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 versions or guarantee byte-for-byte output stability.

Custom templates can emit Python outside the standard generated model patterns covered by `builtin`, so
custom-template output is not exhaustively validated. If `--formatters builtin` produces invalid or poorly formatted
output with a custom template, please open an issue with a small reproducer. See
[Formatter Behavior](formatter-behavior.md) for details.

See [Performance Benchmarks](performance-benchmarks.md) for release benchmark data and interactive charts.
<!-- END AUTO-GENERATED PRESET QUICK START -->

---

## Generate a server or a client

From an OpenAPI document, the same run that generates the models can also generate a FastAPI server package
(`--generate-server fastapi`) or an HTTPX2 client package (`--generate-client httpx2`) that use those models.
Both are experimental since 0.84.0 (see [Experimental Features](experimental.md)). See the
[overview example](index.md#generate-a-fastapi-server-or-an-http-client-experimental),
[FastAPI Server Generation](fastapi-server.md), and [Python Client Generation](python-client.md).

---

## Next Steps

- [Choose an input format](index.md#choose-your-input)
- [Review presets](presets.md)
- [Browse the CLI reference](cli-reference/index.md)

---

# Presets

Source: https://datamodel-code-generator.koxudaxi.dev/presets/

<!-- Generated by scripts/build_preset_docs.py. Do not edit manually. -->

Presets are immutable named groups of CLI options. A preset name never changes behavior; new recommendations are published as new dated preset names.

Every preset name includes its Python target, so generated Python syntax is pinned without an extra `--target-python-version` argument. Choose the preset name instead of adding a separate target option to normal preset commands; if an explicit target is already present in CLI or pyproject configuration, it must match the preset name.

See also: [CLI Reference](cli-reference/index.md), [`--preset`](cli-reference/base-options.md#preset), [`--target-python-version`](cli-reference/model-customization.md#target-python-version), [`--output-model-type`](cli-reference/model-customization.md#output-model-type), [`--profile`](cli-reference/utility-options.md#profile), [`--generate-pyproject-config`](cli-reference/general-options.md#generate-pyproject-config), [`--generate-cli-command`](cli-reference/general-options.md#generate-cli-command), [pyproject.toml configuration](pyproject_toml.md), and [CI/CD integration](ci-cd.md).

## Usage

Use a preset by passing its immutable name:

```bash
datamodel-codegen \
  --input schema.json \
  --input-file-type jsonschema \
  --output-model-type pydantic_v2.BaseModel \
  --preset standard-py312-20261015 \
  --output model.py
```

Use `standard-py312-20261015` for the project-recommended modern Python 3.12 baseline. Use `practical-py312-20261015` when you also want schema-authored names, model reuse, and schema descriptions embedded in the generated code.

Presets dated 20260909 or later select builtin to avoid running external formatters. For project-wide Ruff consistency, use the preset with `--formatters ruff-check ruff-format`. Keep `--formatters black isort` to preserve existing Black/isort output. Earlier dated presets are unchanged. Black and isort remain required installation dependencies.

The 20261015 presets keep the 20260909 options and add Python 3.15 targets.

## Override Preset Options

Preset options are defaults, not locks. Explicit options override preset-supplied values.

```bash
datamodel-codegen \
  --input schema.json \
  --preset standard-py312-20261015 \
  --no-snake-case-field \
  --no-use-annotated \
  --enum-field-as-literal none
```

Use documented `--no-*` options for boolean settings that support negation. For value options, pass the replacement value explicitly, such as `--enum-field-as-literal none`.

## Add Options On Top

You can add any normal CLI option to a preset command. This is the recommended way to start from a preset and make a project-specific choice:

```bash
datamodel-codegen \
  --input schema.json \
  --preset standard-py312-20261015 \
  --extra-fields forbid \
  --use-title-as-name \
  --output model.py
```

## Use Presets With Profiles

Presets can live in `[tool.datamodel-codegen]` or in a named profile. Profiles are useful when one repository generates several model sets:

```toml title="pyproject.toml"
[tool.datamodel-codegen]
output-model-type = "pydantic_v2.BaseModel"
preset = "standard-py312-20261015"

[tool.datamodel-codegen.profiles.api]
input = "schemas/api.json"
output = "src/models/api.py"
preset = "practical-py312-20261015"
extra-fields = "forbid"

[tool.datamodel-codegen.profiles.events]
input = "schemas/events.json"
output = "src/models/events.py"
use-title-as-name = true
```

```bash
datamodel-codegen --profile api
datamodel-codegen --profile events
```

If `--preset` is passed on the CLI, it overrides pyproject preset settings and pyproject options unless the same option is also explicit on the CLI. If `preset` is configured in `pyproject.toml`, pyproject/profile options and CLI options override preset-supplied values.

## Export Configuration

To convert a working preset command into `pyproject.toml`, use `--generate-pyproject-config`:

```bash
datamodel-codegen \
  --input schema.json \
  --output model.py \
  --output-model-type pydantic_v2.BaseModel \
  --preset practical-py312-20261015 \
  --extra-fields forbid \
  --generate-pyproject-config
```

To inspect the effective CLI command for an existing pyproject profile, use `--generate-cli-command`:

```bash
datamodel-codegen --profile api --generate-cli-command
```

Use `--ignore-pyproject` when you want to test a preset command without loading project configuration.

## Built-in Presets

### Target Matrix

| Python target | Standard preset | Practical preset |
|---------------|-----------------|------------------|
| 3.10 | `standard-py310-20261015` | `practical-py310-20261015` |
| 3.11 | `standard-py311-20261015` | `practical-py311-20261015` |
| 3.12 | `standard-py312-20261015` | `practical-py312-20261015` |
| 3.13 | `standard-py313-20261015` | `practical-py313-20261015` |
| 3.14 | `standard-py314-20261015` | `practical-py314-20261015` |
| 3.15 | `standard-py315-20261015` | `practical-py315-20261015` |

Each preset name includes its Python target. Do not add `--target-python-version` just to use a preset; only expanded configuration without `--preset` needs a separate target option.

### Preset Reference

### `standard-py310-20260619`

Recommended modern Python 3.10 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.10. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.10

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.10. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.10"
    use-annotated = true
    use-frozen-field = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.10 --use-annotated --use-frozen-field --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |

### `standard-py311-20260619`

Recommended modern Python 3.11 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.11. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.11

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.11. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.11"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.11 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |

### `standard-py312-20260619`

Recommended modern Python 3.12 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.12. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.12

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.12. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.12"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.12 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |

### `standard-py313-20260619`

Recommended modern Python 3.13 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.13. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.13

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.13. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.13"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.13 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |

### `standard-py314-20260619`

Recommended modern Python 3.14 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.14. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.14

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.14. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.14"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.14 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |

### `practical-py310-20260619`

Standard Python 3.10 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py310-20260619` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.10

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.10. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.10"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.10 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py311-20260619`

Standard Python 3.11 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py311-20260619` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.11

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.11. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.11"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.11 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py312-20260619`

Standard Python 3.12 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py312-20260619` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.12

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.12. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.12"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.12 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py313-20260619`

Standard Python 3.13 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py313-20260619` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.13

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.13. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.13"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.13 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py314-20260619`

Standard Python 3.14 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py314-20260619` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.14

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.14. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    set-default-enum-member = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.14"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --set-default-enum-member --snake-case-field --strict-nullable --target-python-version 3.14 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--set-default-enum-member`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, enum-member defaults, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `standard-py310-20260826`

Recommended modern Python 3.10 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.10. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.10

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.10. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.10"
    use-annotated = true
    use-frozen-field = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.10 --use-annotated --use-frozen-field --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |

### `standard-py311-20260826`

Recommended modern Python 3.11 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.11. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.11

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.11. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.11"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.11 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |

### `standard-py312-20260826`

Recommended modern Python 3.12 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.12. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.12

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.12. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.12"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.12 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |

### `standard-py313-20260826`

Recommended modern Python 3.13 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.13. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.13

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.13. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.13"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.13 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |

### `standard-py314-20260826`

Recommended modern Python 3.14 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.14. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.14

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.14. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.14"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.14 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |

### `practical-py310-20260826`

Standard Python 3.10 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py310-20260826` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.10

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.10. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.10"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.10 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py311-20260826`

Standard Python 3.11 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py311-20260826` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.11

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.11. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.11"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.11 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py312-20260826`

Standard Python 3.12 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py312-20260826` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.12

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.12. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.12"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.12 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py313-20260826`

Standard Python 3.13 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py313-20260826` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.13

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.13. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.13"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.13 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py314-20260826`

Standard Python 3.14 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py314-20260826` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.14

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.14. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.14"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.14 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `standard-py310-20260909`

Recommended modern Python 3.10 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.10. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.10

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.10. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.10"
    use-annotated = true
    use-frozen-field = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.10 --use-annotated --use-frozen-field --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py311-20260909`

Recommended modern Python 3.11 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.11. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.11

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.11. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.11"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.11 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py312-20260909`

Recommended modern Python 3.12 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.12. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.12

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.12. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.12"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.12 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py313-20260909`

Recommended modern Python 3.13 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.13. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.13

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.13. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.13"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.13 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py314-20260909`

Recommended modern Python 3.14 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.14. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.14

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.14. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.14"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.14 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `practical-py310-20260909`

Standard Python 3.10 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py310-20260909` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.10

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.10. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.10"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.10 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py311-20260909`

Standard Python 3.11 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py311-20260909` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.11

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.11. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.11"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.11 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py312-20260909`

Standard Python 3.12 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py312-20260909` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.12

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.12. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.12"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.12 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py313-20260909`

Standard Python 3.13 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py313-20260909` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.13

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.13. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.13"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.13 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py314-20260909`

Standard Python 3.14 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py314-20260909` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.14

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.14. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.14"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.14 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `standard-py310-20261015`

Recommended modern Python 3.10 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.10. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.10

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.10. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.10"
    use-annotated = true
    use-frozen-field = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.10 --use-annotated --use-frozen-field --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py311-20261015`

Recommended modern Python 3.11 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.11. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.11

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.11. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.11"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.11 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py312-20261015`

Recommended modern Python 3.12 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.12. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.12

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.12. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.12"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.12 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py313-20261015`

Recommended modern Python 3.13 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.13. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.13

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.13. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.13"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.13 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py314-20261015`

Recommended modern Python 3.14 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.14. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.14

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.14. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.14"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.14 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `standard-py315-20261015`

Recommended modern Python 3.15 output for new projects.

This immutable preset enables the project-recommended Python output style for new code targeting Python 3.15. It is output-model aware and keeps stdlib dataclass and TypedDict keys compatible with their input names.

- **Requires separate target Python version:** no
- **Target Python version:** 3.15

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.15. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.15"
    use-annotated = true
    use-frozen-field = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-union-operator = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel --snake-case-field --strict-nullable --target-python-version 3.15 --use-annotated --use-frozen-field --use-specialized-enum --use-standard-collections --use-subclass-enum --use-union-operator
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |

### `practical-py310-20261015`

Standard Python 3.10 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py310-20261015` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.10

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.10. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.10"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.10 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py311-20261015`

Standard Python 3.11 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py311-20261015` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.11

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.11. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.11"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.11 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py312-20261015`

Standard Python 3.12 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py312-20261015` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.12

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.12. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.12"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.12 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py313-20261015`

Standard Python 3.13 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py313-20261015` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.13

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.13. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.13"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.13 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py314-20261015`

Standard Python 3.14 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py314-20261015` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.14

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.14. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.14"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.14 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

### `practical-py315-20261015`

Standard Python 3.15 output plus practical naming, deduplication, and schema documentation.

This immutable preset extends `standard-py315-20261015` with options that make generated models easier to read and use in real projects. It favors schema-authored names, model reuse, and embedded schema documentation over the most conservative output-shape stability.

- **Requires separate target Python version:** no
- **Target Python version:** 3.15

#### Included Options

These snippets show the equivalent expanded configuration without `--preset` for JSON Schema input, Pydantic v2 BaseModel output, and Python 3.15. Replace the input and output paths for your project.

=== "pyproject.toml"

    ```toml
    [tool.datamodel-codegen]
    allow-population-by-field-name = true
    collapse-reuse-models = true
    collapse-root-models = true
    deserialize-default-values = ["decimal", "enum"]
    disable-timestamp = true
    enum-field-as-literal = "one"
    formatters = ["builtin"]
    input = "schema.json"
    input-file-type = "jsonschema"
    naming-strategy = "primary-first"
    output = "model.py"
    output-model-type = "pydantic_v2.BaseModel"
    reuse-model = true
    snake-case-field = true
    strict-nullable = true
    target-python-version = "3.15"
    use-annotated = true
    use-default-kwarg = true
    use-field-description = true
    use-field-description-example = true
    use-frozen-field = true
    use-object-type = true
    use-schema-description = true
    use-single-line-docstring = true
    use-specialized-enum = true
    use-standard-collections = true
    use-subclass-enum = true
    use-title-as-name = true
    use-tuple-for-fixed-items = true
    use-union-operator = true
    use-unique-items-as-set = true
    ```

=== "CLI"

    ```bash
    datamodel-codegen --allow-population-by-field-name --collapse-reuse-models --collapse-root-models --deserialize-default-values decimal enum --disable-timestamp --enum-field-as-literal one --formatters builtin --input schema.json --input-file-type jsonschema --naming-strategy primary-first --output model.py --output-model-type pydantic_v2.BaseModel --reuse-model --snake-case-field --strict-nullable --target-python-version 3.15 --use-annotated --use-default-kwarg --use-field-description --use-field-description-example --use-frozen-field --use-object-type --use-schema-description --use-single-line-docstring --use-specialized-enum --use-standard-collections --use-subclass-enum --use-title-as-name --use-tuple-for-fixed-items --use-union-operator --use-unique-items-as-set
    ```

| Scope | Options | Notes |
|-------|---------|-------|
| All output model types | `--use-standard-collections`, `--use-union-operator`, `--use-annotated`, `--enum-field-as-literal one`, `--use-subclass-enum`, `--collapse-root-models`, `--strict-nullable`, `--disable-timestamp` | Use built-in collection syntax, PEP 604 unions, Annotated constraints, single-value enum Literals, typed enum subclasses, inline root wrappers, schema-accurate nullability, and reproducible file headers. |
| Python 3.11+ targets | `--use-specialized-enum` | Use StrEnum or IntEnum only when the selected target Python version supports it. |
| Pydantic v2 BaseModel and dataclass output | `--snake-case-field`, `--allow-population-by-field-name`, `--use-frozen-field` | Generate Pythonic field names while preserving input aliases and readOnly immutability metadata. |
| msgspec Struct output | `--snake-case-field`, `--use-standard-primitive-types` | Generate Pythonic field names with aliases and stdlib primitive types for schema formats. |
| stdlib dataclass output | `--use-standard-primitive-types` | Use stdlib primitive types without renaming input keys because dataclasses do not carry aliases. |
| TypedDict output | `--use-standard-primitive-types`, `--use-frozen-field` | Use stdlib primitive types and ReadOnly metadata without renaming dictionary keys. |
| Serialized defaults | `--deserialize-default-values decimal enum` | Deserialize compatible serialized Decimal and enum defaults into generated Python values while preserving defaults that cannot be converted safely. |
| Built-in formatting | `--formatters builtin` | Format generated models without running an external formatter. For projects using Ruff, override with --formatters ruff-check ruff-format. To preserve Black/isort formatting, override with --formatters black isort. |
| Practical model structure and names | `--reuse-model`, `--collapse-reuse-models`, `--use-title-as-name`, `--naming-strategy primary-first` | Deduplicate identical models without empty inheritance wrappers, prefer schema titles for class names, and keep primary definitions ahead of inline duplicate names. |
| Practical typing and defaults | `--use-default-kwarg`, `--use-object-type`, `--use-tuple-for-fixed-items`, `--use-unique-items-as-set`, `--use-single-line-docstring` | Render defaults explicitly, prefer object for unconstrained values, preserve fixed and unique arrays, and keep short docstrings concise. |
| Schema documentation | `--use-schema-description`, `--use-field-description`, `--use-field-description-example` | Preserve schema and field descriptions, including examples, in generated model documentation. |

---

# Playground

Source: https://datamodel-code-generator.koxudaxi.dev/playground/

Run datamodel-code-generator in your browser. The deployed site serves this route as a standalone app so Pyodide only starts after you open it.

!!! note "Playground privacy"
    The playground runs entirely in your browser with Pyodide. Your schema, selected input type, and options are passed
    to the local Pyodide worker for generation and are not posted to a backend server.

    Use **Copy Repro URL** in the playground to share the current input schema, input type, and selected options in the
    URL fragment. When a playground version is selected, **Copy Repro URL** keeps the selected `?version=` in the shared
    URL. The fragment part (`#state=...`) is client-side URL state and is not included in HTTP requests, so the encoded
    schema and options are not sent to the hosting server or Cloudflare by opening the link. The complete URL, including
    the fragment, can still be stored in local browser history and is visible to anyone or any service you share it
    with. The optional `?version=` query parameter is sent in normal page requests, so hosting/CDN metrics can record the
    selected playground version but not the encoded schema or options.

<p>
  <a class="md-button md-button--primary" href="../assets/playground/index.html">Open Playground</a>
</p>

---

# Supported Input Formats

Source: https://datamodel-code-generator.koxudaxi.dev/supported-data-types/

This code generator supports the following input formats:

- OpenAPI 3.0/3.1/3.2 (YAML/JSON, [OpenAPI Data Types](https://spec.openapis.org/oas/v3.2.0.html#data-types)); OpenAPI 2.0 (Swagger) has limited support.
- [AsyncAPI](asyncapi.md) 2.x/3.x (YAML/JSON).
- JSON Schema ([JSON Schema Core](https://json-schema.org/draft/2020-12/json-schema-core.html) / [JSON Schema Validation](https://json-schema.org/draft/2020-12/json-schema-validation.html)).
- Apache Avro schema (`.avsc`, [Apache Avro](avro.md)).
- [XML Schema](xmlschema.md) (XSD).
- Protocol Buffers / gRPC (`.proto`, [Protocol Buffers / gRPC](protobuf.md)).
- GraphQL schema ([GraphQL Schemas and Types](https://graphql.org/learn/schema/)).
- MCP tool schemas (`--input-file-type mcp-tools`, [MCP Tool Schemas](mcp-tools.md)).
- JSON / YAML / CSV data (converted to JSON Schema before model generation).
- Python dictionary (converted to JSON Schema before model generation).
- Existing Python types via [`--input-model`](python-model.md): Pydantic models, dataclasses, Pydantic dataclasses, TypedDict, and dict schemas.

Use `--input-file-type auto` (the default) for common files, or set an explicit
type when a file extension is ambiguous. For example, YAML can contain either an
OpenAPI/JSON Schema document or raw sample data, so use `jsonschema`, `openapi`,
or `yaml` depending on the intended input.

## Input Format Guide

<!-- BEGIN AUTO-GENERATED INPUT FORMAT GUIDE -->
### Input Format Guide (from code)

The tables below are generated from the input type enum, parser routing code, schema version enums, raw-data conversion rules, and parser type conversion maps.

#### Parser Routes and Version Flags

| Input format | Selector | Parser route | `--schema-version` | Auto detection |
| --- | --- | --- | --- | --- |
| JSON Schema | `jsonschema` | `JsonSchemaParser` | `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | `$schema`, `type`, `properties`, or composition keywords |
| OpenAPI | `openapi` | `OpenAPIParser` | `3.0`, `3.1`, `3.2`, `auto` | `openapi` field |
| AsyncAPI | `asyncapi` | `AsyncAPIParser` | `2.0`, `3.0`, `auto` | `asyncapi` field |
| GraphQL schema | `graphql` | `GraphQLParser` | Not supported | Explicit only |
| XML Schema | `xmlschema` | `XMLSchemaParser` | `1.0`, `1.1`, `auto` | XML Schema namespace on the root element |
| Protocol Buffers | `protobuf` | `ProtobufParser` | `proto2`, `proto3`, `2023`, `auto` | Protocol Buffers syntax/message-like text |
| Apache Avro | `avro` | `AvroParser` | Not supported | Avro schema object, union, or primitive schema form |
| MCP tool schemas | `mcp-tools` | `JsonSchemaParser after MCP conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Explicit only |
| JSON data | `json` | `JsonSchemaParser after genson conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Mapping that is not a schema/OpenAPI/AsyncAPI/Avro document |
| YAML data | `yaml` | `JsonSchemaParser after genson conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Explicit for YAML sample data |
| CSV data | `csv` | `JsonSchemaParser after genson conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Detected from CSV-like text with consistent comma counts across non-empty lines or explicit `csv` |
| Python dictionary data | `dict` | `JsonSchemaParser after genson conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Explicit for mapping input |
| Python input model | `--input-model` | `JsonSchemaParser` after Python schema conversion | JSON Schema after conversion; dict input can select another explicit schema type | Explicit only |

#### Accepted Source Shapes

| Input format | Accepted source shape |
| --- | --- |
| JSON Schema | JSON Schema document as JSON/YAML, mapping, URL, or file |
| OpenAPI | OpenAPI document as JSON/YAML, mapping, URL, or file |
| AsyncAPI | AsyncAPI document as JSON/YAML, mapping, URL, or file |
| GraphQL schema | GraphQL SDL text, URL, or file |
| XML Schema | XSD XML text, URL, or file |
| Protocol Buffers | .proto text, file, directory, URL, or path list |
| Apache Avro | Avro schema JSON/YAML, mapping, list, URL, or file |
| MCP tool schemas | MCP tool list/profile as JSON/YAML, mapping, list, URL, or file |
| JSON data | JSON sample data text or file |
| YAML data | YAML sample data text or file |
| CSV data | CSV text or file with a header row and at least one data row |
| Python dictionary data | In-memory mapping or Python literal data |
| Python input model | `module:Object` or `path/to/file.py:Object` via `--input-model` |

#### Format Type Coverage

| Input family | Code-derived coverage | Guide |
| --- | --- | --- |
| JSON Schema | 7 schema types, 54 common formats | Uses JSON Schema type/format mappings and feature metadata below |
| OpenAPI | JSON Schema mappings plus 2 OpenAPI-only formats | Adds OpenAPI-specific schema features and formats |
| GraphQL | 6 GraphQL type kinds | Uses GraphQL SDL parser order and parser method map |
| XML Schema | 50 built-in XSD datatypes | Converts XSD built-ins to JSON Schema fragments |
| Protocol Buffers | 15 scalar field types, 17 well-known type mappings | Converts descriptors to JSON Schema definitions |
| Apache Avro | 8 primitives, 13 logical type mappings | Converts Avro schemas to JSON Schema while preserving Avro metadata |
| JSON/YAML/CSV/Dict data | 4 raw data selectors | Samples are converted to JSON Schema with genson before parsing |
| Python input model | 4 supported object kinds | Python objects are converted to schema data before normal generation |

#### GraphQL Type Kinds

| GraphQL kind | Parser method | Generated shape |
| --- | --- | --- |
| `scalar` | `parse_scalar` | Generates scalar aliases |
| `enum` | `parse_enum` | Generates enums or literals depending on enum options |
| `interface` | `parse_interface` | Generates model classes from interface fields |
| `object` | `parse_object` | Generates model classes except root Query/Mutation objects |
| `input_object` | `parse_input_object` | Generates model classes for input objects |
| `union` | `parse_union` | Generates union type aliases |

#### Apache Avro Primitive Types

| Avro primitive | JSON Schema mapping | Constraints |
| --- | --- | --- |
| `null` | `null` | - |
| `boolean` | `boolean` | - |
| `int` | `integer` + `int32` | - |
| `long` | `integer` + `int64` | - |
| `float` | `number` + `float` | - |
| `double` | `number` + `double` | - |
| `bytes` | `string` + `binary` | - |
| `string` | `string` | - |

#### Apache Avro Logical Types

| Avro logical type | Allowed Avro type | JSON Schema mapping |
| --- | --- | --- |
| `decimal` | `bytes`, `fixed` | `string` + `decimal` |
| `big-decimal` | `bytes` | `string` + `decimal` |
| `uuid` | `string`, `fixed` | `string` + `uuid` |
| `date` | `int` | `string` + `date` |
| `time-millis` | `int` | `string` + `time` |
| `time-micros` | `long` | `string` + `time` |
| `timestamp-millis` | `long` | `string` + `date-time` |
| `timestamp-micros` | `long` | `string` + `date-time` |
| `timestamp-nanos` | `long` | `string` + `date-time` |
| `local-timestamp-millis` | `long` | `string` + `date-time-local` |
| `local-timestamp-micros` | `long` | `string` + `date-time-local` |
| `local-timestamp-nanos` | `long` | `string` + `date-time-local` |
| `duration` | `fixed` | `string` + `duration` |

#### Protocol Buffers Scalar Types

| Protobuf scalar | JSON Schema mapping | Constraints |
| --- | --- | --- |
| `double` | `number` + `double` | - |
| `float` | `number` + `float` | - |
| `int64` | `integer` + `int64` | - |
| `uint64` | `integer` + `int64` | minimum=0, maximum=18446744073709551615 |
| `int32` | `integer` + `int32` | - |
| `uint32` | `integer` + `int32` | minimum=0, maximum=4294967295 |
| `sint32` | `integer` + `int32` | - |
| `sint64` | `integer` + `int64` | - |
| `fixed32` | `integer` + `int32` | minimum=0, maximum=4294967295 |
| `fixed64` | `integer` + `int64` | minimum=0, maximum=18446744073709551615 |
| `sfixed32` | `integer` + `int32` | - |
| `sfixed64` | `integer` + `int64` | - |
| `bool` | `boolean` | - |
| `string` | `string` | - |
| `bytes` | `string` + `binary` | - |

#### Protocol Buffers Well-Known Types

| Well-known type | JSON Schema mapping |
| --- | --- |
| `google.protobuf.Timestamp` | `string` + `date-time` |
| `google.protobuf.Duration` | `string` + `duration` |
| `google.protobuf.Struct` | `object` map |
| `google.protobuf.ListValue` | `array` |
| `google.protobuf.Value` | `null` \| `boolean` \| `number` \| `string` \| `object` map \| `array` |
| `google.protobuf.Any` | `object` map |
| `google.protobuf.Empty` | `object` |
| `google.protobuf.FieldMask` | `string` |
| `google.protobuf.DoubleValue` | `number` + `double` \| `null` |
| `google.protobuf.FloatValue` | `number` + `float` \| `null` |
| `google.protobuf.Int64Value` | `integer` + `int64` \| `null` |
| `google.protobuf.UInt64Value` | `integer` + `int64` \| `null` |
| `google.protobuf.Int32Value` | `integer` + `int32` \| `null` |
| `google.protobuf.UInt32Value` | `integer` + `int32` \| `null` |
| `google.protobuf.BoolValue` | `boolean` \| `null` |
| `google.protobuf.StringValue` | `string` \| `null` |
| `google.protobuf.BytesValue` | `string` + `binary` \| `null` |

#### XML Schema Built-In Type Groups

| JSON Schema mapping | XSD built-ins | Count |
| --- | --- | --- |
| `Any` | `anySimpleType`, `anyAtomicType`, `anyType` | 3 |
| `string` + `uri` | `anyURI` | 1 |
| `string` + `byte` | `base64Binary` | 1 |
| `boolean` | `boolean` | 1 |
| `integer` | `byte`, `int`, `integer`, `long`, `negativeInteger`, `nonNegativeInteger`, `nonPositiveInteger`, `positiveInteger`, +5 more | 13 |
| `string` + `date` | `date` | 1 |
| `string` + `date-time` | `dateTime`, `dateTimeStamp` | 2 |
| `number` + `decimal` | `decimal` | 1 |
| `number` | `double`, `float` | 2 |
| `string` | `duration`, `ENTITY`, `gDay`, `gMonth`, `gMonthDay`, `gYear`, `gYearMonth`, `hexBinary`, +12 more | 20 |
| `string` + `duration` | `dayTimeDuration` | 1 |
| `array` | `ENTITIES`, `IDREFS`, `NMTOKENS` | 3 |
| `string` + `time` | `time` | 1 |

#### Python Input Types

| Python input object | Conversion behavior |
| --- | --- |
| `dict` | Returned directly as the schema; `--input-file-type` is required |
| `Pydantic v2 BaseModel` | Converted with Pydantic `model_json_schema()` |
| `dataclass` | Converted with Pydantic `TypeAdapter`; includes stdlib and Pydantic dataclasses |
| `TypedDict` | Converted with Pydantic `TypeAdapter` |
| Multiple `--input-model` | Supported only for Pydantic v2 BaseModel classes |
<!-- END AUTO-GENERATED INPUT FORMAT GUIDE -->

## 📘 OpenAPI 3 and JSON Schema {#openapi-3-and-json-schema}

Below are the data types and features recognized by datamodel-code-generator for OpenAPI 3 and JSON Schema.

<!-- BEGIN AUTO-GENERATED SCHEMA FEATURE SUPPORT -->
### Schema Feature Support (from code)

The JSON Schema and OpenAPI feature matrix below is generated from the same code metadata used by the schema version support page.

#### JSON Schema Features

| Feature | Introduced | Status | Description |
|---------|------------|--------|-------------|
| `Null in type array` | Draft 4 or earlier | ✅ Supported | Allows `type: ['string', 'null']` syntax for nullable types |
| `$defs` | 2019-09 | ✅ Supported | Uses `$defs` instead of `definitions` for schema definitions |
| `prefixItems` | 2020-12 | ✅ Supported | Tuple validation using `prefixItems` keyword |
| `Boolean schemas` | Draft 6 | ✅ Supported | Allows `true` and `false` as valid schemas |
| `$id` | Draft 6 | ✅ Supported | Schema identifier field (`id` in Draft 4, `$id` in Draft 6+) |
| `definitions/$defs` | Draft 4 | ✅ Supported | Key for reusable schema definitions |
| `exclusiveMinimum/Maximum as number` | Draft 6 | ✅ Supported | Numeric `exclusiveMinimum`/`exclusiveMaximum` (boolean in Draft 4) |
| `readOnly/writeOnly` | Draft 7 | ✅ Supported | Field visibility hints for read-only and write-only properties |
| `const` | Draft 6 | ✅ Supported | Single constant value constraint |
| `propertyNames` | Draft 6 | ✅ Supported | Dict key type constraints via pattern, enum, or $ref |
| `contains` | Draft 6 | ⚠️ Partial | Count constraints are modeled when contains matches every item; general schema-valued contains is not supported |
| `deprecated` | 2019-09 | ⚠️ Partial | Marks schema elements as deprecated |
| `if/then/else` | Draft 7 | ❌ Not Supported | Conditional schema validation |
| `contentMediaType/contentEncoding` | Draft 7 | ⚠️ Partial | Content type and encoding hints for strings |
| `contentSchema` | 2019-09 | ⚠️ Partial | Schema for decoded string content |
| `$anchor` | 2019-09 | ✅ Supported | Location-independent schema references |
| `$vocabulary` | 2019-09 | ❌ Not Supported | Vocabulary declarations for meta-schemas |
| `unevaluatedProperties` | 2019-09 | ⚠️ Partial | Additional properties not evaluated by subschemas |
| `unevaluatedItems` | 2019-09 | ⚠️ Partial | Additional items not evaluated by subschemas |
| `dependentRequired` | 2019-09 | ❌ Not Supported | Conditional property requirements |
| `dependentSchemas` | 2019-09 | ❌ Not Supported | Conditional schema application based on property presence |
| `$recursiveRef/$recursiveAnchor` | 2019-09 | ✅ Supported | Recursive reference resolution via anchors |
| `$dynamicRef/$dynamicAnchor` | 2020-12 | ✅ Supported | Dynamic reference resolution across schemas |

#### OpenAPI-Specific Features

| Feature | Introduced | Status | Description |
|---------|------------|--------|-------------|
| `nullable` | OAS 3.0 | ✅ Supported | Uses `nullable: true` for nullable types (deprecated in 3.1) |
| `discriminator` | OAS 3.0 | ✅ Supported | Polymorphism support via `discriminator` keyword |
| `webhooks` | OAS 3.1 | ✅ Supported | Top-level webhooks object for incoming events |
| `$ref with sibling keywords` | OAS 3.1 | ⚠️ Partial | $ref can coexist with description, summary (no allOf workaround) |
| `itemSchema` | OAS 3.2 | ✅ Supported | Media Type Object item schema for sequential media |
| `$self` | OAS 3.2 | ✅ Supported | Root document URI for relative and absolute reference resolution |
| `querystring` | OAS 3.2 | ✅ Supported | Query string parameter object without a parameter name |
| `xml` | OAS 3.0 | ⚠️ Partial | XML serialization metadata (name, namespace, prefix) |
| `externalDocs` | OAS 3.0 | ⚠️ Partial | Reference to external documentation |
| `links` | OAS 3.0 | ❌ Not Supported | Links between operations |
| `callbacks` | OAS 3.0 | ❌ Not Supported | Callback definitions for webhooks |
| `securitySchemes` | OAS 3.0 | ❌ Not Supported | API security mechanism definitions |
<!-- END AUTO-GENERATED SCHEMA FEATURE SUPPORT -->

## ✅ Implemented data types and features

<!-- BEGIN AUTO-GENERATED DATA TYPE SUPPORT -->
### Implemented Data Types and Formats

The schema type, format, and default Pydantic v2 type columns below are generated from the parser's schema format registry and the default Pydantic v2 type mapping; keyword and note columns document supplemental schema details.

#### Schema Data Types

| Schema Type | Default Pydantic v2 Type | Supported Keywords |
|-------------|--------------------------|--------------------|
| `integer` | `int` | maximum, exclusiveMaximum, minimum, exclusiveMinimum, multipleOf |
| `number` | `float` | maximum, exclusiveMaximum, minimum, exclusiveMinimum, multipleOf |
| `string` | `str` | pattern, minLength, maxLength |
| `boolean` | `bool` | - |
| `object` | `Dict[str, Any]` | properties, required, additionalProperties, patternProperties |
| `null` | `None` | - |
| `array` | `List[Any]` | items, prefixItems, minItems, maxItems, uniqueItems |

#### Common Formats (JSON Schema + OpenAPI)

| Schema Type | Format | Default Pydantic v2 Type | Notes |
|-------------|--------|--------------------------|-------|
| `integer` | `default` (no `format`) | `int` | - |
| `integer` | `int32` | `int` | - |
| `integer` | `int64` | `int` | - |
| `integer` | `date-time` | `AwareDatetime` | - |
| `integer` | `unix-time` | `int` | - |
| `integer` | `unixtime` | `int` | - |
| `number` | `default` (no `format`) | `float` | - |
| `number` | `float` | `float` | - |
| `number` | `double` | `float` | - |
| `number` | `decimal` | `Decimal` | - |
| `number` | `date-time` | `AwareDatetime` | - |
| `number` | `time` | `time` | - |
| `number` | `time-delta` | `timedelta` | - |
| `number` | `unixtime` | `int` | - |
| `string` | `default` (no `format`) | `str` | - |
| `string` | `byte` | `Base64Str` | Base64 encoded string |
| `string` | `date` | `date` | - |
| `string` | `date-time` | `AwareDatetime` | - |
| `string` | `timestamp with time zone` | `AwareDatetime` | - |
| `string` | `date-time-local` | `NaiveDatetime` | - |
| `string` | `duration` | `timedelta` | - |
| `string` | `time` | `time` | - |
| `string` | `time-local` | `time` | - |
| `string` | `path` | `Path` | - |
| `string` | `email` | `EmailStr` | Requires email-validator |
| `string` | `idn-email` | `EmailStr` | Requires email-validator |
| `string` | `idn-hostname` | `str` | - |
| `string` | `iri` | `str` | - |
| `string` | `iri-reference` | `str` | - |
| `string` | `uuid` | `UUID` | - |
| `string` | `uuid1` | `UUID1` | - |
| `string` | `uuid2` | `UUID` | - |
| `string` | `uuid3` | `UUID3` | - |
| `string` | `uuid4` | `UUID4` | - |
| `string` | `uuid5` | `UUID5` | - |
| `string` | `uri` | `AnyUrl` | - |
| `string` | `uri-reference` | `str` | - |
| `string` | `uri-template` | `str` | - |
| `string` | `json-pointer` | `str` | - |
| `string` | `relative-json-pointer` | `str` | - |
| `string` | `regex` | `str` | - |
| `string` | `hostname` | `str` | - |
| `string` | `ipv4` | `IPv4Address` | - |
| `string` | `ipv4-network` | `IPv4Network` | - |
| `string` | `ipv6` | `IPv6Address` | - |
| `string` | `ipv6-network` | `IPv6Network` | - |
| `string` | `decimal` | `Decimal` | - |
| `string` | `integer` | `int` | - |
| `string` | `unixtime` | `int` | - |
| `string` | `ulid` | `ULID` | Requires python-ulid |
| `boolean` | `default` (no `format`) | `bool` | - |
| `object` | `default` (no `format`) | `Dict[str, Any]` | - |
| `null` | `default` (no `format`) | `None` | - |
| `array` | `default` (no `format`) | `List[Any]` | - |

#### OpenAPI-Only Formats

| Schema Type | Format | Default Pydantic v2 Type | Notes |
|-------------|--------|--------------------------|-------|
| `string` | `binary` | `bytes` | File content |
| `string` | `password` | `SecretStr` | - |
<!-- END AUTO-GENERATED DATA TYPE SUPPORT -->

### 🔗 Other schema
- enum (as enum.Enum or typing.Literal)
- allOf (as Multiple inheritance)
- anyOf (as typing.Union)
- oneOf (as typing.Union)
- $ref ([http extra](index.md#http-extra-option) is required when resolving $ref for remote files.)
- $id (for [JSONSchema](https://json-schema.org/understanding-json-schema/structuring.html#id))

---

# Schema Version Support

Source: https://datamodel-code-generator.koxudaxi.dev/supported_formats/

This document describes the JSON Schema, OpenAPI, AsyncAPI, Apache Avro, XML Schema, and Protocol Buffers versions supported by datamodel-code-generator.

## Overview

datamodel-code-generator supports multiple schema formats including JSON Schema, OpenAPI, AsyncAPI, Apache Avro, XML Schema, and Protocol Buffers. By default, the tool operates in **Lenient mode**, accepting all features regardless of version declarations for formats that carry version information. This ensures maximum compatibility with real-world schemas that often mix features from different versions.

## Input Format Guide

<!-- BEGIN AUTO-GENERATED INPUT FORMAT GUIDE -->
### Input Format Guide (from code)

The tables below are generated from the input type enum, parser routing code, schema version enums, raw-data conversion rules, and parser type conversion maps.

#### Parser Routes and Version Flags

| Input format | Selector | Parser route | `--schema-version` | Auto detection |
| --- | --- | --- | --- | --- |
| JSON Schema | `jsonschema` | `JsonSchemaParser` | `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | `$schema`, `type`, `properties`, or composition keywords |
| OpenAPI | `openapi` | `OpenAPIParser` | `3.0`, `3.1`, `3.2`, `auto` | `openapi` field |
| AsyncAPI | `asyncapi` | `AsyncAPIParser` | `2.0`, `3.0`, `auto` | `asyncapi` field |
| GraphQL schema | `graphql` | `GraphQLParser` | Not supported | Explicit only |
| XML Schema | `xmlschema` | `XMLSchemaParser` | `1.0`, `1.1`, `auto` | XML Schema namespace on the root element |
| Protocol Buffers | `protobuf` | `ProtobufParser` | `proto2`, `proto3`, `2023`, `auto` | Protocol Buffers syntax/message-like text |
| Apache Avro | `avro` | `AvroParser` | Not supported | Avro schema object, union, or primitive schema form |
| MCP tool schemas | `mcp-tools` | `JsonSchemaParser after MCP conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Explicit only |
| JSON data | `json` | `JsonSchemaParser after genson conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Mapping that is not a schema/OpenAPI/AsyncAPI/Avro document |
| YAML data | `yaml` | `JsonSchemaParser after genson conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Explicit for YAML sample data |
| CSV data | `csv` | `JsonSchemaParser after genson conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Detected from CSV-like text with consistent comma counts across non-empty lines or explicit `csv` |
| Python dictionary data | `dict` | `JsonSchemaParser after genson conversion` | Converted to JSON Schema; `draft-04`, `draft-06`, `draft-07`, `2019-09`, `2020-12`, `auto` | Explicit for mapping input |
| Python input model | `--input-model` | `JsonSchemaParser` after Python schema conversion | JSON Schema after conversion; dict input can select another explicit schema type | Explicit only |

#### Accepted Source Shapes

| Input format | Accepted source shape |
| --- | --- |
| JSON Schema | JSON Schema document as JSON/YAML, mapping, URL, or file |
| OpenAPI | OpenAPI document as JSON/YAML, mapping, URL, or file |
| AsyncAPI | AsyncAPI document as JSON/YAML, mapping, URL, or file |
| GraphQL schema | GraphQL SDL text, URL, or file |
| XML Schema | XSD XML text, URL, or file |
| Protocol Buffers | .proto text, file, directory, URL, or path list |
| Apache Avro | Avro schema JSON/YAML, mapping, list, URL, or file |
| MCP tool schemas | MCP tool list/profile as JSON/YAML, mapping, list, URL, or file |
| JSON data | JSON sample data text or file |
| YAML data | YAML sample data text or file |
| CSV data | CSV text or file with a header row and at least one data row |
| Python dictionary data | In-memory mapping or Python literal data |
| Python input model | `module:Object` or `path/to/file.py:Object` via `--input-model` |

#### Format Type Coverage

| Input family | Code-derived coverage | Guide |
| --- | --- | --- |
| JSON Schema | 7 schema types, 54 common formats | Uses JSON Schema type/format mappings and feature metadata below |
| OpenAPI | JSON Schema mappings plus 2 OpenAPI-only formats | Adds OpenAPI-specific schema features and formats |
| GraphQL | 6 GraphQL type kinds | Uses GraphQL SDL parser order and parser method map |
| XML Schema | 50 built-in XSD datatypes | Converts XSD built-ins to JSON Schema fragments |
| Protocol Buffers | 15 scalar field types, 17 well-known type mappings | Converts descriptors to JSON Schema definitions |
| Apache Avro | 8 primitives, 13 logical type mappings | Converts Avro schemas to JSON Schema while preserving Avro metadata |
| JSON/YAML/CSV/Dict data | 4 raw data selectors | Samples are converted to JSON Schema with genson before parsing |
| Python input model | 4 supported object kinds | Python objects are converted to schema data before normal generation |

#### GraphQL Type Kinds

| GraphQL kind | Parser method | Generated shape |
| --- | --- | --- |
| `scalar` | `parse_scalar` | Generates scalar aliases |
| `enum` | `parse_enum` | Generates enums or literals depending on enum options |
| `interface` | `parse_interface` | Generates model classes from interface fields |
| `object` | `parse_object` | Generates model classes except root Query/Mutation objects |
| `input_object` | `parse_input_object` | Generates model classes for input objects |
| `union` | `parse_union` | Generates union type aliases |

#### Apache Avro Primitive Types

| Avro primitive | JSON Schema mapping | Constraints |
| --- | --- | --- |
| `null` | `null` | - |
| `boolean` | `boolean` | - |
| `int` | `integer` + `int32` | - |
| `long` | `integer` + `int64` | - |
| `float` | `number` + `float` | - |
| `double` | `number` + `double` | - |
| `bytes` | `string` + `binary` | - |
| `string` | `string` | - |

#### Apache Avro Logical Types

| Avro logical type | Allowed Avro type | JSON Schema mapping |
| --- | --- | --- |
| `decimal` | `bytes`, `fixed` | `string` + `decimal` |
| `big-decimal` | `bytes` | `string` + `decimal` |
| `uuid` | `string`, `fixed` | `string` + `uuid` |
| `date` | `int` | `string` + `date` |
| `time-millis` | `int` | `string` + `time` |
| `time-micros` | `long` | `string` + `time` |
| `timestamp-millis` | `long` | `string` + `date-time` |
| `timestamp-micros` | `long` | `string` + `date-time` |
| `timestamp-nanos` | `long` | `string` + `date-time` |
| `local-timestamp-millis` | `long` | `string` + `date-time-local` |
| `local-timestamp-micros` | `long` | `string` + `date-time-local` |
| `local-timestamp-nanos` | `long` | `string` + `date-time-local` |
| `duration` | `fixed` | `string` + `duration` |

#### Protocol Buffers Scalar Types

| Protobuf scalar | JSON Schema mapping | Constraints |
| --- | --- | --- |
| `double` | `number` + `double` | - |
| `float` | `number` + `float` | - |
| `int64` | `integer` + `int64` | - |
| `uint64` | `integer` + `int64` | minimum=0, maximum=18446744073709551615 |
| `int32` | `integer` + `int32` | - |
| `uint32` | `integer` + `int32` | minimum=0, maximum=4294967295 |
| `sint32` | `integer` + `int32` | - |
| `sint64` | `integer` + `int64` | - |
| `fixed32` | `integer` + `int32` | minimum=0, maximum=4294967295 |
| `fixed64` | `integer` + `int64` | minimum=0, maximum=18446744073709551615 |
| `sfixed32` | `integer` + `int32` | - |
| `sfixed64` | `integer` + `int64` | - |
| `bool` | `boolean` | - |
| `string` | `string` | - |
| `bytes` | `string` + `binary` | - |

#### Protocol Buffers Well-Known Types

| Well-known type | JSON Schema mapping |
| --- | --- |
| `google.protobuf.Timestamp` | `string` + `date-time` |
| `google.protobuf.Duration` | `string` + `duration` |
| `google.protobuf.Struct` | `object` map |
| `google.protobuf.ListValue` | `array` |
| `google.protobuf.Value` | `null` \| `boolean` \| `number` \| `string` \| `object` map \| `array` |
| `google.protobuf.Any` | `object` map |
| `google.protobuf.Empty` | `object` |
| `google.protobuf.FieldMask` | `string` |
| `google.protobuf.DoubleValue` | `number` + `double` \| `null` |
| `google.protobuf.FloatValue` | `number` + `float` \| `null` |
| `google.protobuf.Int64Value` | `integer` + `int64` \| `null` |
| `google.protobuf.UInt64Value` | `integer` + `int64` \| `null` |
| `google.protobuf.Int32Value` | `integer` + `int32` \| `null` |
| `google.protobuf.UInt32Value` | `integer` + `int32` \| `null` |
| `google.protobuf.BoolValue` | `boolean` \| `null` |
| `google.protobuf.StringValue` | `string` \| `null` |
| `google.protobuf.BytesValue` | `string` + `binary` \| `null` |

#### XML Schema Built-In Type Groups

| JSON Schema mapping | XSD built-ins | Count |
| --- | --- | --- |
| `Any` | `anySimpleType`, `anyAtomicType`, `anyType` | 3 |
| `string` + `uri` | `anyURI` | 1 |
| `string` + `byte` | `base64Binary` | 1 |
| `boolean` | `boolean` | 1 |
| `integer` | `byte`, `int`, `integer`, `long`, `negativeInteger`, `nonNegativeInteger`, `nonPositiveInteger`, `positiveInteger`, +5 more | 13 |
| `string` + `date` | `date` | 1 |
| `string` + `date-time` | `dateTime`, `dateTimeStamp` | 2 |
| `number` + `decimal` | `decimal` | 1 |
| `number` | `double`, `float` | 2 |
| `string` | `duration`, `ENTITY`, `gDay`, `gMonth`, `gMonthDay`, `gYear`, `gYearMonth`, `hexBinary`, +12 more | 20 |
| `string` + `duration` | `dayTimeDuration` | 1 |
| `array` | `ENTITIES`, `IDREFS`, `NMTOKENS` | 3 |
| `string` + `time` | `time` | 1 |

#### Python Input Types

| Python input object | Conversion behavior |
| --- | --- |
| `dict` | Returned directly as the schema; `--input-file-type` is required |
| `Pydantic v2 BaseModel` | Converted with Pydantic `model_json_schema()` |
| `dataclass` | Converted with Pydantic `TypeAdapter`; includes stdlib and Pydantic dataclasses |
| `TypedDict` | Converted with Pydantic `TypeAdapter` |
| Multiple `--input-model` | Supported only for Pydantic v2 BaseModel classes |
<!-- END AUTO-GENERATED INPUT FORMAT GUIDE -->

## JSON Schema Version Support

### Supported Versions

| Version | Spec URL | Notes |
|---------|----------|-------|
| Draft 4 | [json-schema.org/draft-04](https://json-schema.org/draft-04/json-schema-core) | `id`, `definitions` |
| Draft 6 | [json-schema.org/draft-06](https://json-schema.org/draft-06/json-schema-release-notes) | `$id`, const, boolean schemas |
| Draft 7 | [json-schema.org/draft-07](https://json-schema.org/draft-07/json-schema-release-notes) | if/then/else, readOnly/writeOnly |
| 2019-09 | [json-schema.org/draft/2019-09](https://json-schema.org/draft/2019-09/release-notes) | `$defs`, `$anchor`, `$recursiveRef`/`$recursiveAnchor` |
| 2020-12 | [json-schema.org/draft/2020-12](https://json-schema.org/draft/2020-12/release-notes) | `prefixItems`, `$dynamicRef`/`$dynamicAnchor` |

### Feature Compatibility Matrix

| Feature | Draft 4 | Draft 6 | Draft 7 | 2019-09 | 2020-12 |
|---------|---------|---------|---------|---------|---------|
| **ID/Reference** |
| ID field | `id` | `$id` | `$id` | `$id` | `$id` |
| Definitions key | `definitions` | `definitions` | `definitions` | `$defs`* | `$defs` |
| **Type Features** |
| Boolean schemas | - | Yes | Yes | Yes | Yes |
| Null in type array | Yes | Yes | Yes | Yes | Yes |
| const | - | Yes | Yes | Yes | Yes |
| **Numeric Constraints** |
| exclusiveMinimum (number) | - (boolean) | Yes | Yes | Yes | Yes |
| exclusiveMaximum (number) | - (boolean) | Yes | Yes | Yes | Yes |
| **Array Features** |
| prefixItems | - | - | - | - | Yes |
| items (as array/tuple) | Yes | Yes | Yes | Yes | - (single only) |
| contains | - | Yes | Yes | Yes | Yes |
| **Conditional** |
| if/then/else | - | - | Yes | Yes | Yes |
| **Recursive/Dynamic References** | | | | | |
| `$recursiveRef` / `$recursiveAnchor` | - | - | - | Yes | - |
| `$dynamicRef` / `$dynamicAnchor` | - | - | - | - | Yes |
| **Metadata** |
| readOnly | - | - | Yes | Yes | Yes |
| writeOnly | - | - | Yes | Yes | Yes |

*2019-09 supports both `definitions` and `$defs` for backward compatibility.

### Version Detection

datamodel-code-generator automatically detects the JSON Schema version:

1. **Explicit `$schema` field**: If present, the version is detected from the URL pattern
2. **Heuristics**: If no `$schema`, presence of `$defs` suggests 2020-12, `definitions` suggests Draft 7
3. **Fallback**: Draft 7 (backward-compatible default)

### Embedded Schema Resources

Nested `$id` declarations identify embedded schema resources. References to these resources resolve within the containing document before any file or HTTP lookup. Relative references inside each resource use its own URI as their base, and JSON pointers and anchors are scoped to that resource.

## OpenAPI Version Support

### Supported Versions

| Version | Spec URL | JSON Schema Base |
|---------|----------|------------------|
| 3.0.x | [spec.openapis.org/oas/v3.0.3](https://spec.openapis.org/oas/v3.0.3) | Draft 5 (subset) |
| 3.1.x | [spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) | 2020-12 (full) |
| 3.2.x | [spec.openapis.org/oas/v3.2.0](https://spec.openapis.org/oas/v3.2.0) | 2020-12 (full) |

> **Note**: OpenAPI 2.0 (Swagger) support is limited. We recommend converting to OpenAPI 3.0+.

### Feature Compatibility Matrix

| Feature | OAS 3.0 | OAS 3.1 | OAS 3.2 |
|---------|---------|---------|---------|
| **Schema Base** | JSON Schema Draft 5 (subset) | JSON Schema 2020-12 (full) | JSON Schema 2020-12 (full) |
| **Definitions Path** | `#/components/schemas` | `#/components/schemas` | `#/components/schemas` |
| **Nullable** | | | |
| `nullable: true` keyword | Yes | Deprecated | Deprecated |
| Null in type array | - | Yes | Yes |
| Type as array | - | Yes | Yes |
| **Array Features** | | | |
| prefixItems | - | Yes | Yes |
| **Boolean Schemas** | - | Yes | Yes |
| **OpenAPI Specific** | | | |
| discriminator | Yes | Yes | Yes |
| binary format | Yes | Yes | Yes |
| password format | Yes | Yes | Yes |
| webhooks | - | Yes | Yes |

### Version Detection

datamodel-code-generator detects the OpenAPI version from the `openapi` field:

- `openapi: "3.0.x"` -> OpenAPI 3.0
- `openapi: "3.1.x"` -> OpenAPI 3.1
- `openapi: "3.2.x"` -> OpenAPI 3.2
- No `openapi` field -> Fallback to OpenAPI 3.1

## AsyncAPI Version Support

AsyncAPI documents are supported with `--input-file-type asyncapi`. The parser generates models from schema-bearing message payloads, headers, and reusable schemas.

### Supported Versions

| Version | Schema behavior |
|---------|-----------------|
| 2.x | Message `schemaFormat` is applied to `payload`; default schemas use OpenAPI 3.0-compatible features |
| 3.x | `payload`, `headers`, and `components.schemas` may use Schema Object, Reference Object, or Multi Format Schema Object; default schemas use OpenAPI 3.1-compatible features |

### Supported Schema Locations

| Location | Status | Notes |
|----------|--------|-------|
| `components.schemas` | ✅ Supported | Reusable schemas are generated even when not referenced |
| `components.messages[*].payload` / `headers` | ✅ Supported | Includes local and external references |
| Channel `publish` / `subscribe` messages | ✅ Supported | AsyncAPI 2.x channel operation messages |
| Channel `messages` | ✅ Supported | AsyncAPI 3.x channel messages |
| Operation `messages` / `reply.messages` | ✅ Supported | Includes reusable `components.operations` |
| Message trait `headers` | ✅ Supported | Used when the target message does not define `headers` |
| Protocol bindings | ⚠️ Tolerated | Binding configuration is transport metadata and is not emitted as models |

### Embedded Schema Formats

| `schemaFormat` family | Status | Notes |
|-----------------------|--------|-------|
| AsyncAPI Schema Object | ✅ Supported | Default when omitted |
| JSON Schema | ✅ Supported | `application/schema+json` and `application/schema+yaml` |
| OpenAPI Schema Object | ✅ Supported | `application/vnd.oai.openapi...` |
| Apache Avro | ✅ Supported | `application/vnd.apache.avro...` |
| Protocol Buffers | ✅ Supported | `application/vnd.google.protobuf`; inline source and local imports are resolved |
| XML Schema | ✅ Supported | `application/xml`, `text/xml`, `application/xsd+xml`, `application/xml+schema`, `application/xml-schema` |
| RAML and custom formats | ❌ Explicit error | Use a dedicated top-level input type where available |

### Version Detection

datamodel-code-generator detects the AsyncAPI version from the `asyncapi` field:

- `asyncapi: "2.x.y"` -> AsyncAPI 2.x
- `asyncapi: "3.x.y"` -> AsyncAPI 3.x
- Unknown versions fall back to the 3.x schema behavior unless `--schema-version` is set explicitly

## MCP Tool Schema Profile Support

MCP tool schema profile documents are supported with `--input-file-type mcp-tools`. This input type is experimental and converts MCP tool `inputSchema` and `outputSchema` entries into JSON Schema definitions before model generation.

Supported source shapes include:

- `tools/list` JSON-RPC responses with `result.tools`;
- MCP server definitions with a top-level `tools` array;
- single tool definitions or arrays of tool definitions;
- JSON Schema documents whose `$defs` or `definitions` values are tool definitions.

Each generated definition is named from the tool `name` plus `Input` or `Output`, for example `SearchInput`, `SearchOutput`, and `CreateIssueInput`.

## Protocol Buffers Version Support

### Supported Versions

| Version | Spec URL | Notes |
|---------|----------|-------|
| proto2 | [protobuf.dev/reference/protobuf/proto2-spec](https://protobuf.dev/reference/protobuf/proto2-spec/) | `required`, `optional`, `repeated`, defaults, extensions |
| proto3 | [protobuf.dev/reference/protobuf/proto3-spec](https://protobuf.dev/reference/protobuf/proto3-spec/) | implicit field defaults, `optional`, maps, services |
| edition 2023 | [protobuf.dev/editions](https://protobuf.dev/programming-guides/editions/) | Supported by the bundled `protoc` runtime |

### Version Detection

datamodel-code-generator detects Protocol Buffers syntax from each compiled `.proto` descriptor:

- `syntax = "proto3";` -> proto3
- `syntax = "proto2";` or no syntax declaration -> proto2
- `edition = "2023";` -> edition 2023
- `--schema-version proto2`, `--schema-version proto3`, or `--schema-version 2023` can override
  auto-detection

## Apache Avro Schema Support

JSON-encoded Apache Avro schemas are supported with `--input-file-type avro`. The parser accepts `.avsc` files and Avro schema JSON.

### Supported Schema Forms

| Avro construct | Status | Notes |
|----------------|--------|-------|
| Primitive types | ✅ Supported | `null`, `boolean`, `int`, `long`, `float`, `double`, `bytes`, `string` |
| `record` | ✅ Supported | Generates Python model classes |
| `enum` | ✅ Supported | Generates enum classes |
| `array` | ✅ Supported | Generates list fields or root list models |
| `map` | ✅ Supported | Generates dict fields or root dict models |
| `fixed` | ✅ Supported | Generates fixed-length binary string models |
| `union` | ✅ Supported | Generates union types; nullable unions become optional fields |
| Named type resolution | ✅ Supported | Handles `name`, `namespace`, fullnames, nested named types, and references |
| Record field metadata | ✅ Supported | Preserves `doc`, `default`, `aliases`, and `order` where applicable |
| Logical types | ✅ Supported | Maps current Avro logical types to Python-friendly formats where possible |

### Logical Types

| Avro logical type | Python-oriented format |
|-------------------|------------------------|
| `decimal`, `big-decimal` | Decimal |
| `uuid` | UUID |
| `date` | Date |
| `time-millis`, `time-micros` | Time |
| `timestamp-millis`, `timestamp-micros`, `timestamp-nanos` | Date-time |
| `local-timestamp-millis`, `local-timestamp-micros`, `local-timestamp-nanos` | Local date-time |
| `duration` | Timedelta/duration |

### Version Detection

Apache Avro schemas do not include an in-schema version marker equivalent to JSON Schema's `$schema`, OpenAPI's `openapi`, or XML Schema versioning attributes. For that reason, `--schema-version` does not select an Avro specification version. The Avro parser follows the currently implemented Apache Avro schema rules and logical types.

### Avro Limitations

datamodel-code-generator generates Python model definitions from Avro schemas. It does not implement Avro runtime validation, binary encoding, decoding, or serialization.

<!-- BEGIN AUTO-GENERATED SUPPORTED FEATURES -->
### Supported Features (from code)

The following features are tracked in the codebase with their implementation status:

#### JSON Schema Features

| Feature | Introduced | Status | Description |
|---------|------------|--------|-------------|
| `Null in type array` | Draft 4 or earlier | ✅ Supported | Allows `type: ['string', 'null']` syntax for nullable types |
| `$defs` | 2019-09 | ✅ Supported | Uses `$defs` instead of `definitions` for schema definitions |
| `prefixItems` | 2020-12 | ✅ Supported | Tuple validation using `prefixItems` keyword |
| `Boolean schemas` | Draft 6 | ✅ Supported | Allows `true` and `false` as valid schemas |
| `$id` | Draft 6 | ✅ Supported | Schema identifier field (`id` in Draft 4, `$id` in Draft 6+) |
| `definitions/$defs` | Draft 4 | ✅ Supported | Key for reusable schema definitions |
| `exclusiveMinimum/Maximum as number` | Draft 6 | ✅ Supported | Numeric `exclusiveMinimum`/`exclusiveMaximum` (boolean in Draft 4) |
| `readOnly/writeOnly` | Draft 7 | ✅ Supported | Field visibility hints for read-only and write-only properties |
| `const` | Draft 6 | ✅ Supported | Single constant value constraint |
| `propertyNames` | Draft 6 | ✅ Supported | Dict key type constraints via pattern, enum, or $ref |
| `contains` | Draft 6 | ⚠️ Partial | Count constraints are modeled when contains matches every item; general schema-valued contains is not supported |
| `deprecated` | 2019-09 | ⚠️ Partial | Marks schema elements as deprecated |
| `if/then/else` | Draft 7 | ❌ Not Supported | Conditional schema validation |
| `contentMediaType/contentEncoding` | Draft 7 | ⚠️ Partial | Content type and encoding hints for strings |
| `contentSchema` | 2019-09 | ⚠️ Partial | Schema for decoded string content |
| `$anchor` | 2019-09 | ✅ Supported | Location-independent schema references |
| `$vocabulary` | 2019-09 | ❌ Not Supported | Vocabulary declarations for meta-schemas |
| `unevaluatedProperties` | 2019-09 | ⚠️ Partial | Additional properties not evaluated by subschemas |
| `unevaluatedItems` | 2019-09 | ⚠️ Partial | Additional items not evaluated by subschemas |
| `dependentRequired` | 2019-09 | ❌ Not Supported | Conditional property requirements |
| `dependentSchemas` | 2019-09 | ❌ Not Supported | Conditional schema application based on property presence |
| `$recursiveRef/$recursiveAnchor` | 2019-09 | ✅ Supported | Recursive reference resolution via anchors |
| `$dynamicRef/$dynamicAnchor` | 2020-12 | ✅ Supported | Dynamic reference resolution across schemas |

#### OpenAPI-Specific Features

| Feature | Introduced | Status | Description |
|---------|------------|--------|-------------|
| `nullable` | OAS 3.0 | ✅ Supported | Uses `nullable: true` for nullable types (deprecated in 3.1) |
| `discriminator` | OAS 3.0 | ✅ Supported | Polymorphism support via `discriminator` keyword |
| `webhooks` | OAS 3.1 | ✅ Supported | Top-level webhooks object for incoming events |
| `$ref with sibling keywords` | OAS 3.1 | ⚠️ Partial | $ref can coexist with description, summary (no allOf workaround) |
| `itemSchema` | OAS 3.2 | ✅ Supported | Media Type Object item schema for sequential media |
| `$self` | OAS 3.2 | ✅ Supported | Root document URI for relative and absolute reference resolution |
| `querystring` | OAS 3.2 | ✅ Supported | Query string parameter object without a parameter name |
| `xml` | OAS 3.0 | ⚠️ Partial | XML serialization metadata (name, namespace, prefix) |
| `externalDocs` | OAS 3.0 | ⚠️ Partial | Reference to external documentation |
| `links` | OAS 3.0 | ❌ Not Supported | Links between operations |
| `callbacks` | OAS 3.0 | ❌ Not Supported | Callback definitions for webhooks |
| `securitySchemes` | OAS 3.0 | ❌ Not Supported | API security mechanism definitions |
<!-- END AUTO-GENERATED SUPPORTED FEATURES -->

## Data Format Support

<!-- BEGIN AUTO-GENERATED DATA FORMAT SUPPORT -->
### Data Format Support

The schema type, format, and default Pydantic v2 type columns below are generated from the schema format registry and the default Pydantic v2 type mapping; notes document supplemental details.

#### Common Formats (JSON Schema + OpenAPI)

| Schema Type | Format | Default Pydantic v2 Type | Notes |
|-------------|--------|--------------------------|-------|
| `integer` | `default` (no `format`) | `int` | - |
| `integer` | `int32` | `int` | - |
| `integer` | `int64` | `int` | - |
| `integer` | `date-time` | `AwareDatetime` | - |
| `integer` | `unix-time` | `int` | - |
| `integer` | `unixtime` | `int` | - |
| `number` | `default` (no `format`) | `float` | - |
| `number` | `float` | `float` | - |
| `number` | `double` | `float` | - |
| `number` | `decimal` | `Decimal` | - |
| `number` | `date-time` | `AwareDatetime` | - |
| `number` | `time` | `time` | - |
| `number` | `time-delta` | `timedelta` | - |
| `number` | `unixtime` | `int` | - |
| `string` | `default` (no `format`) | `str` | - |
| `string` | `byte` | `Base64Str` | Base64 encoded string |
| `string` | `date` | `date` | - |
| `string` | `date-time` | `AwareDatetime` | - |
| `string` | `timestamp with time zone` | `AwareDatetime` | - |
| `string` | `date-time-local` | `NaiveDatetime` | - |
| `string` | `duration` | `timedelta` | - |
| `string` | `time` | `time` | - |
| `string` | `time-local` | `time` | - |
| `string` | `path` | `Path` | - |
| `string` | `email` | `EmailStr` | Requires email-validator |
| `string` | `idn-email` | `EmailStr` | Requires email-validator |
| `string` | `idn-hostname` | `str` | - |
| `string` | `iri` | `str` | - |
| `string` | `iri-reference` | `str` | - |
| `string` | `uuid` | `UUID` | - |
| `string` | `uuid1` | `UUID1` | - |
| `string` | `uuid2` | `UUID` | - |
| `string` | `uuid3` | `UUID3` | - |
| `string` | `uuid4` | `UUID4` | - |
| `string` | `uuid5` | `UUID5` | - |
| `string` | `uri` | `AnyUrl` | - |
| `string` | `uri-reference` | `str` | - |
| `string` | `uri-template` | `str` | - |
| `string` | `json-pointer` | `str` | - |
| `string` | `relative-json-pointer` | `str` | - |
| `string` | `regex` | `str` | - |
| `string` | `hostname` | `str` | - |
| `string` | `ipv4` | `IPv4Address` | - |
| `string` | `ipv4-network` | `IPv4Network` | - |
| `string` | `ipv6` | `IPv6Address` | - |
| `string` | `ipv6-network` | `IPv6Network` | - |
| `string` | `decimal` | `Decimal` | - |
| `string` | `integer` | `int` | - |
| `string` | `unixtime` | `int` | - |
| `string` | `ulid` | `ULID` | Requires python-ulid |
| `boolean` | `default` (no `format`) | `bool` | - |
| `object` | `default` (no `format`) | `Dict[str, Any]` | - |
| `null` | `default` (no `format`) | `None` | - |
| `array` | `default` (no `format`) | `List[Any]` | - |

#### OpenAPI-Only Formats

| Schema Type | Format | Default Pydantic v2 Type | Notes |
|-------------|--------|--------------------------|-------|
| `string` | `binary` | `bytes` | File content |
| `string` | `password` | `SecretStr` | - |
<!-- END AUTO-GENERATED DATA FORMAT SUPPORT -->

## Limitations and Known Issues

### JSON Schema - Unsupported Features

| Feature | Introduced | Status | Notes |
|---------|------------|--------|-------|
| `contains` | Draft 6 | ⚠️ Partial | Count constraints are modeled when `contains` matches every item |
| `unevaluatedProperties` | 2019-09 | ⚠️ Partial | Boolean values and schema-valued extra allowance are modeled |
| `unevaluatedItems` | 2019-09 | ⚠️ Partial | Boolean values and schema-valued array item types are modeled |
| `contentMediaType` | Draft 7 | ⚠️ Partial | Preserved as schema metadata |
| `contentEncoding` | Draft 7 | ⚠️ Partial | Preserved as schema metadata |
| `contentSchema` | 2019-09 | ⚠️ Partial | Preserved as schema metadata |
| `$vocabulary` | 2019-09 | ❌ Not supported | Vocabulary declarations ignored |
| `$comment` | Draft 7 | ⚠️ Ignored | Comments not preserved in output |
| `deprecated` | 2019-09 | ⚠️ Partial | Recognized but not enforced |
| `examples` (array) | Draft 6 | ⚠️ Partial | Only first example used for Field default |
| Recursive `$ref` | Draft 4+ | ⚠️ Partial | Supported with `ForwardRef`, may require manual adjustment |
| `propertyNames` | Draft 6 | ✅ Supported | Dict key type constraints via pattern, enum, or $ref |
| `dependentRequired` | 2019-09 | ❌ Not supported | Dependent requirements ignored |
| `dependentSchemas` | 2019-09 | ❌ Not supported | Dependent schemas ignored |

### OpenAPI - Unsupported Features

| Feature | Introduced | Status | Notes |
|---------|------------|--------|-------|
| OpenAPI 2.0 (Swagger) | OAS 2.0 | ⚠️ Limited | Recommend converting to 3.0+ |
| `$ref` sibling keywords | OAS 3.0 | ❌ Not supported | 3.0 spec limitation (fixed in 3.1) |
| `links` | OAS 3.0 | ❌ Not supported | Runtime linking not applicable |
| `callbacks` | OAS 3.0 | ❌ Not supported | Webhook callbacks ignored |
| `webhooks` | OAS 3.1 | ✅ Supported | Generated when included in `--openapi-scopes` |
| `security` definitions | OAS 2.0+ | ❌ Not supported | Security schemes not generated |
| `servers` | OAS 3.0 | ❌ Not supported | Server configuration ignored |
| `externalDocs` | OAS 2.0+ | ⚠️ Partial | Preserved as schema metadata |
| `xml` | OAS 2.0+ | ⚠️ Partial | Preserved as schema metadata |
| Request body `required` | OAS 3.0 | ⚠️ Partial | Affects field optionality |
| Header/Cookie parameters | OAS 3.0 | ⚠️ Partial | Generated but not validated |

### Apache Avro - Unsupported Features

| Feature | Status | Notes |
|---------|--------|-------|
| Runtime validation | ❌ Not supported | Generated models are Python models, not an Avro validator |
| Avro binary serialization | ❌ Not supported | Encoding and decoding are outside model generation scope |
| Avro container files | ❌ Not supported | Input is schema JSON / `.avsc`, not Avro data files |

### GraphQL - Unsupported Features

| Feature | Spec | Status | Notes |
|---------|------|--------|-------|
| Directives | Core | ❌ Not supported | Custom directives ignored |
| Subscriptions | Core | ❌ Not supported | Only Query/Mutation types |
| Custom scalars | Core | ⚠️ Partial | Mapped to `Any` by default |
| Interfaces inheritance | Core | ⚠️ Partial | Flattened to concrete types |
| Federation directives | Apollo | ❌ Not supported | Apollo Federation not supported |
| Input unions | Proposal | ❌ Not supported | Not yet in GraphQL spec |

### Legend

- ✅ Fully supported
- ⚠️ Partial support or limitations
- ❌ Not supported

### Mixed Version Schemas

Real-world schemas often mix features from different versions. datamodel-code-generator handles this in **Lenient mode** (default):

- Features from all versions are accepted
- No warnings for version mismatches
- Maximum compatibility with existing schemas

In **Strict mode** (`--schema-version-mode strict`), warnings are emitted for version-incompatible features.

## See Also

- [Supported Data Types](./supported-data-types.md) - Complete data type support
- [JSON Schema Guide](./jsonschema.md) - JSON Schema usage examples
- [OpenAPI Guide](./openapi.md) - OpenAPI usage examples
- [AsyncAPI Guide](./asyncapi.md) - AsyncAPI usage examples
- [Apache Avro Guide](./avro.md) - Avro schema usage examples
- [Protocol Buffers / gRPC Guide](./protobuf.md) - Protocol Buffers schema usage examples

---

# Generate from OpenAPI

Source: https://datamodel-code-generator.koxudaxi.dev/openapi/

Generate Pydantic models from OpenAPI 3 schema definitions.

This page covers OpenAPI input behavior and examples. For task-oriented OpenAPI options, see
[OpenAPI Options](openapi-options.md). For the generated option reference, see
[CLI Reference: OpenAPI-only Options](cli-reference/openapi-only-options.md).

## 🚀 Quick Start

```bash
datamodel-codegen --input api.yaml --input-file-type openapi --output model.py
```

## 📝 Example

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: openapi.quick-start.schema -->
<details>
<summary>api.yaml</summary>

<!-- fmt: off -->

```yaml
openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            format: int32
      responses:
        '200':
          description: A paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
                x-amazon-apigateway-integration:
                  uri:
                    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                  passthroughBehavior: when_no_templates
                  httpMethod: POST
                  type: aws_proxy
    post:
      summary: Create a pet
      operationId: createPets
      tags:
        - pets
      responses:
        '201':
          description: Null response
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
                x-amazon-apigateway-integration:
                  uri:
                    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                  passthroughBehavior: when_no_templates
                  httpMethod: POST
                  type: aws_proxy
  /pets/{petId}:
    get:
      summary: Info for a specific pet
      operationId: showPetById
      tags:
        - pets
      parameters:
        - name: petId
          in: path
          required: true
          description: The id of the pet to retrieve
          schema:
            type: string
      responses:
        '200':
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    x-amazon-apigateway-integration:
      uri:
        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
      passthroughBehavior: when_no_templates
      httpMethod: POST
      type: aws_proxy
components:
  schemas:
    Pet:
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
          default: 1
        name:
          type: string
        tag:
          type: string
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
    Users:
      type: array
      items:
        required:
          - id
          - name
        properties:
          id:
            type: integer
            format: int64
          name:
            type: string
          tag:
            type: string
    Id:
      type: string
    Rules:
      type: array
      items:
        type: string
    Error:
      description: error result
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string
    apis:
      type: array
      items:
        type: object
        properties:
          apiKey:
            type: string
            description: To be used as a dataset parameter value
          apiVersionNumber:
            type: string
            description: To be used as a version parameter value
          apiUrl:
            type: string
            format: uri
            description: "The URL describing the dataset's fields"
          apiDocumentationUrl:
            type: string
            format: uri
            description: A URL to the API console for each API
    Event:
      type: object
      description: Event object
      properties:
        name:
          type: string
    Result:
        type: object
        properties:
          event:
            $ref: '#/components/schemas/Event'
```

<!-- fmt: on -->
</details>
<!-- END AUTO-GENERATED DOC EXAMPLE: openapi.quick-start.schema -->

**✨ Generated model.py:**

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: openapi.quick-start.output -->
<!-- fmt: off -->

```python
from __future__ import annotations

from pydantic import AnyUrl, BaseModel, Field, RootModel


class Pet(BaseModel):
    id: int
    name: str
    tag: str | None = None


class Pets(RootModel[list[Pet]]):
    root: list[Pet]


class User(BaseModel):
    id: int
    name: str
    tag: str | None = None


class Users(RootModel[list[User]]):
    root: list[User]


class Id(RootModel[str]):
    root: str


class Rules(RootModel[list[str]]):
    root: list[str]


class Error(BaseModel):
    code: int
    message: str


class Api(BaseModel):
    apiKey: str | None = Field(
        None, description='To be used as a dataset parameter value'
    )
    apiVersionNumber: str | None = Field(
        None, description='To be used as a version parameter value'
    )
    apiUrl: AnyUrl | None = Field(
        None, description="The URL describing the dataset's fields"
    )
    apiDocumentationUrl: AnyUrl | None = Field(
        None, description='A URL to the API console for each API'
    )


class Apis(RootModel[list[Api]]):
    root: list[Api]


class Event(BaseModel):
    name: str | None = None


class Result(BaseModel):
    event: Event | None = None
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: openapi.quick-start.output -->

---

## 📖 readOnly / writeOnly Properties

OpenAPI 3.x supports `readOnly` and `writeOnly` property annotations:

- 📤 **readOnly**: Property is only returned in responses (e.g., `id`, `created_at`)
- 📥 **writeOnly**: Property is only sent in requests (e.g., `password`)

### ⚙️ Option: `--read-only-write-only-model-type`

This option generates separate Request/Response models based on these annotations.

| Value | Description |
|-------|-------------|
| (not set) | Default. No special handling (backward compatible) |
| `request-response` | Generate only Request/Response models (no base model) |
| `all` | Generate base model + Request + Response models |

### 📋 Example Schema

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: openapi.read-only-write-only.schema -->
<!-- fmt: off -->

```yaml
openapi: "3.0.0"
info:
  title: Read Only Write Only Test API
  version: "1.0"
paths: {}
components:
  schemas:
    User:
      type: object
      required:
        - id
        - name
        - password
      properties:
        id:
          type: integer
          readOnly: true
        name:
          type: string
        password:
          type: string
          writeOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        secret_token:
          type: string
          writeOnly: true
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: openapi.read-only-write-only.schema -->

### ✨ Generated Output

```bash
datamodel-codegen --input user.yaml --input-file-type openapi \
    --output-model-type pydantic_v2.BaseModel \
    --read-only-write-only-model-type all
```

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: openapi.read-only-write-only.output -->
<!-- fmt: off -->

```python
from __future__ import annotations

from pydantic import AwareDatetime, BaseModel


class UserRequest(BaseModel):
    name: str
    password: str
    secret_token: str | None = None


class UserResponse(BaseModel):
    id: int
    name: str
    created_at: AwareDatetime | None = None


class User(BaseModel):
    id: int
    name: str
    password: str
    created_at: AwareDatetime | None = None
    secret_token: str | None = None
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: openapi.read-only-write-only.output -->

### 🎯 Usage Patterns

| Use Case | Recommended Option | Generated Models |
|----------|-------------------|------------------|
| API client validation | `request-response` | `UserRequest`, `UserResponse` |
| Database ORM mapping | (not set) | `User` |
| Both client & ORM | `all` | `User`, `UserRequest`, `UserResponse` |

### 🔗 Behavior with allOf Inheritance

When using `allOf` with `$ref`, fields from all referenced schemas are flattened into Request/Response models:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: openapi.read-only-write-only-allof.schema -->
<!-- fmt: off -->

```yaml
openapi: "3.0.0"
info:
  title: Read Only Write Only AllOf Test API
  version: "1.0"
paths: {}
components:
  schemas:
    Timestamps:
      type: object
      properties:
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true

    Credentials:
      type: object
      properties:
        password:
          type: string
          writeOnly: true
        api_key:
          type: string
          writeOnly: true

    User:
      allOf:
        - $ref: "#/components/schemas/Timestamps"
        - $ref: "#/components/schemas/Credentials"
        - type: object
          required:
            - id
            - name
          properties:
            id:
              type: integer
              readOnly: true
            name:
              type: string
            email:
              type: string
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: openapi.read-only-write-only-allof.schema -->

Generated `UserRequest` will exclude `created_at`, `updated_at`, and `id` because they are readOnly fields from the flattened Timestamps/User schemas. Generated `UserResponse` will exclude `password` and `api_key` because they are writeOnly fields from Credentials.

### ⚠️ Collision Handling

If a schema named `UserRequest` or `UserResponse` already exists, the generated model will be named `UserRequestModel` or `UserResponseModel` to avoid conflicts.

### 📤 Supported Output Formats

This option works with all output formats:

- `pydantic_v2.BaseModel`
- `pydantic_v2.dataclass`
- `dataclasses.dataclass`
- `typing.TypedDict`
- `msgspec.Struct`

### 🔗 Supported $ref Types

readOnly/writeOnly resolution works with local and file reference types:

| Reference Type | Example | Support |
|---------------|---------|---------|
| Local | `#/components/schemas/User` | ✅ Supported |
| File | `./common.yaml#/User` | ✅ Supported |

## Supported OpenAPI Features

| Feature | Generation behavior |
|---------|---------------------|
| `components.schemas` | Default model generation scope |
| `components.parameters` | Resolved when referenced by selected operations; no standalone models for unreferenced entries |
| `paths` operation schemas | Generated with `--openapi-scopes paths` |
| Operation query parameters | Included with `--openapi-scopes paths parameters`; add `--include-path-parameters` for URL path parameters |
| `readOnly` / `writeOnly` | Request/response variants with `--read-only-write-only-model-type` |
| Discriminators and combined schemas | Converted into Python unions and inheritance-aware models where possible |
| Local and file `$ref` | Resolved before model generation |

## Limitations

OpenAPI input is used for model generation. Without the experimental `--generate-server fastapi` or
`--generate-client httpx2` options, it does not generate HTTP clients, server handlers, route definitions, or runtime
request dispatch logic; with them, it also generates a [FastAPI server package](fastapi-server.md) or a
[Python client package](python-client.md) on top of the models. Full OpenAPI document validation is outside the generation path unless you explicitly
enable validation-related options.

---

## 📖 See Also

- 🚀 [Getting Started](getting-started.md) - Installation and first model
- 🖥️ [CLI Reference: OpenAPI-only Options](cli-reference/openapi-only-options.md) - All OpenAPI-specific CLI options
- ⚙️ [CLI Reference: Base Options](cli-reference/base-options.md) - Input/output configuration options

---

# OpenAPI Options

Source: https://datamodel-code-generator.koxudaxi.dev/openapi-options/

<!-- related-cli-options: --openapi-scopes, --include-path-parameters, --use-operation-id-as-name, --read-only-write-only-model-type, --validation -->

# OpenAPI Options

When working with OpenAPI specifications, datamodel-code-generator provides several options to control how schemas, operations, and special properties are handled. This page explains when and how to use each option.

This page is a task-oriented guide for OpenAPI-specific generation behavior. For input format basics, see
[Generate from OpenAPI](openapi.md). For every flag, choice, and generated example, see
[CLI Reference: OpenAPI-only Options](cli-reference/openapi-only-options.md).

## Quick Overview

| Option | Description |
|--------|-------------|
| `--openapi-scopes` | Select which parts of the spec to generate models from |
| `--include-path-parameters` | Include path parameters in generated models |
| `--use-operation-id-as-name` | Name models using operation IDs |
| `--read-only-write-only-model-type` | Generate separate models for request/response contexts |
| `--validation` | Enable OpenAPI validation constraints (deprecated) |

---

## `--openapi-scopes`

Controls which sections of the OpenAPI specification to generate models from.

| Scope | Description |
|-------|-------------|
| `schemas` | Generate from `#/components/schemas` (default) |
| `api` | Generate schema declarations throughout the API, including typed components, parameters, headers, callbacks, and webhooks |
| `parameters` | Include parameter models for operations selected by `paths` or `webhooks` |
| `paths` | Generate models from path operation request bodies and responses |
| `webhooks` | Generate models from webhook operation request bodies and responses |

### Default behavior (schemas only)

```bash
datamodel-codegen --input openapi.yaml --output models.py
```

Generates models only from `#/components/schemas`.

### Generate all API declarations

```bash
datamodel-codegen --input openapi.yaml --output models.py --openapi-scopes api
```

The `api` scope collects component schemas, typed parameter/request-body/response/header
components, root paths, webhooks, reusable Path Items, and callbacks. It includes all
request and response media, response headers, and applicable multipart encoding headers.
OpenAPI version rules determine which declarations apply. Repeated references share
one declaration's generated models, and callback cycles terminate without expanding
models indefinitely.

Parameters generate individual schema types, including path parameters regardless of
`--include-path-parameters`. The legacy aggregate parameter wrapper is specific to the
`parameters` scope without `api`.

Parameter schemas (path, query, header, and cookie parameters) that would be emitted as
root models are emitted exactly as `--use-type-alias` emits them, for every output model
type and option combination: `type LimitParameter = Annotated[int, Field(ge=1, le=100)]`
on Python 3.12+ and `TypeAliasType` below 3.12. Object parameters stay models. Anything
that references a parameter schema, including another schema, references its alias. An
alias has no default value, so the model no longer applies a parameter schema's scalar
default. Component schemas, response headers, and the other scopes keep their usual
models.

!!! note "Changed in 0.84.0"
    With `--openapi-scopes api`, parameter schemas that 0.83.0 generated as root models, such as a Pydantic
    `RootModel`, are now type aliases, as `--use-type-alias` emits them. Code that constructed one, such as
    `LimitParameter(5)`, or read its `.root` uses the plain value instead. See
    [Root Models and Type Aliases](root-model-and-type-alias.md#api-scope-parameters).

!!! note "Changed in 0.84.0"
    With `--openapi-scopes api`, a model derived from a schema inside `paths` is named after the operation without
    the `Field` prefix 0.83.0 put before it: `FieldPetsGetResponse` is now `PetsGetResponse`. The separators of a
    path are dropped, `/` alone becomes `Root` (`RootGetResponse`), and a name that starts with a digit keeps `Field`
    (`Field2faCodesGetResponse` for `/2fa/codes`). A derived name that a component schema already holds takes a
    numeric suffix, so a component `OrdersGetResponse` keeps its name and the model of `GET /orders` becomes
    `OrdersGetResponse1`. Code that imports a derived model by its old name uses the new one instead. Component
    schemas and `$ref` targets keep their names.

!!! note "Changed in 0.84.0"
    With `--openapi-scopes api`, a `$ref` beside only annotations in a parameter, request body, or response schema
    is the referenced model itself, not a derived `RootModel` that wraps it, as it is for a property. The siblings
    that count as annotations are `description`, `title`, `examples`, `example`, `default`, `deprecated`, `readOnly`,
    `writeOnly`, `externalDocs`, `$comment`, and `x-` extensions. A `$ref` beside a keyword that changes its values,
    such as `minLength`, `maxItems`, or `properties`, still has a derived model, and so does one beside
    only `nullable: true`, unlike a property where it becomes `Optional`. See
    [Root Models and Type Aliases](root-model-and-type-alias.md#api-scope-references).

Adding other scopes alongside `api` does not repeat schema generation. `--openapi-include-paths` filters root paths and their reachable
callbacks; webhooks and standalone components retain their declarations.

Use standard JSON Pointer escaping in references: `~1` represents a slash in a key and
`~0` represents a tilde. API scope rejects malformed or ambiguous pointer spellings.
An API with no model declarations emits no model artifact and preserves an existing
output file. Explicit model metadata can still describe an empty inventory.

For Python generation, pass `openapi_scopes=[OpenAPIScope.Api]` to `generate()` or
`GenerateConfig`. Direct parser consumers use
`datamodel_code_generator.parser.openapi_scope.ApiOpenAPIParser` with an
`OpenAPIParserConfig` that explicitly includes `OpenAPIScope.Api`. Existing scopes
continue to use `OpenAPIParser`; the default remains `schemas`.

### Include operation schemas

```bash
datamodel-codegen --input openapi.yaml --output models.py \
  --openapi-scopes schemas paths
```

Also generates models from operation request bodies and responses.

### Include operation parameter models

```bash
datamodel-codegen --input openapi.yaml --output models.py \
  --openapi-scopes schemas parameters paths
```

Also generates a query parameter model for each operation that has query parameters.
Add `--include-path-parameters` to include URL path parameters in these models.
Parameters can be declared inline or referenced from `#/components/parameters`.
Unreferenced entries in `components.parameters` do not generate standalone models,
and the `parameters` scope alone does not select operations.

### When to use each scope

| Use Case | Recommended Scopes |
|----------|-------------------|
| Basic model generation | `schemas` (default) |
| Request and response models | `schemas paths` |
| Request, response, and query parameter models | `schemas paths parameters` |

---

## `--include-path-parameters`

Includes path parameters as fields in generated operation parameter models.
Use this with `--openapi-scopes paths parameters`.

### OpenAPI Example

```yaml
openapi: "3.0.3"
info:
  title: Orders API
  version: "1.0"
paths:
  /users/{user_id}/orders/{order_id}:
    get:
      operationId: getOrder
      parameters:
        - name: user_id
          in: path
          required: true
          schema:
            type: string
        - name: order_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: No content
```

### Without `--include-path-parameters`

Only query parameters are included in operation parameter models. This example
has only path parameters, so it does not generate a parameter model without the flag.

### With `--include-path-parameters`

```bash
datamodel-codegen --input openapi.yaml --output models.py \
  --openapi-scopes paths parameters --include-path-parameters --use-operation-id-as-name
```

```python
class GetOrderParameters(BaseModel):
    user_id: str
    order_id: int
```

### When to use

- Building request validation models that include URL parameters
- Grouping query and URL path parameters in one operation parameter model

---

## `--use-operation-id-as-name`

Uses the `operationId` from OpenAPI operations to name generated models instead of deriving names from paths.

### OpenAPI Example

```yaml
paths:
  /users/{id}:
    get:
      operationId: getUserById
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  id: { type: integer }
                  name: { type: string }
```

### Without `--use-operation-id-as-name`

```python
class UsersIdGetResponse(BaseModel):  # Derived from path
    id: int
    name: str
```

### With `--use-operation-id-as-name`

```bash
datamodel-codegen --input openapi.yaml --output models.py --use-operation-id-as-name
```

```python
class GetUserByIdResponse(BaseModel):  # Uses operationId
    id: int
    name: str
```

### When to use

- When `operationId` values are well-designed and descriptive
- For consistency with generated API clients (e.g., OpenAPI Generator)
- When path-derived names are too verbose or unclear

---

## `--read-only-write-only-model-type`

Generates separate request/response model variants for properties marked as `readOnly` or `writeOnly` in OpenAPI.

See [CLI Reference: `--read-only-write-only-model-type`](cli-reference/openapi-only-options.md#read-only-write-only-model-type) for the full option reference.

### OpenAPI Example

```yaml
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          readOnly: true        # Only in responses
        password:
          type: string
          writeOnly: true       # Only in requests
        name:
          type: string          # In both
```

### Without `--read-only-write-only-model-type`

```python
class User(BaseModel):
    id: Optional[int] = None  # Both included
    password: Optional[str] = None
    name: Optional[str] = None
```

### With `--read-only-write-only-model-type request-response`

```bash
datamodel-codegen --input openapi.yaml --output models.py \
  --read-only-write-only-model-type request-response
```

```python
class UserRequest(BaseModel):
    """For requests - excludes readOnly fields."""

    password: Optional[str] = None
    name: Optional[str] = None


class UserResponse(BaseModel):
    """For responses - excludes writeOnly fields."""

    id: Optional[int] = None
    name: Optional[str] = None
```

Use `all` instead of `request-response` when you also need the base model with all fields.

### Values

| Value | Description |
|-------|-------------|
| `request-response` | Generate request and response variants |
| `all` | Generate the base model plus request and response variants |

### When to use

- APIs with distinct request/response schemas
- Strict type checking for API clients
- When `readOnly`/`writeOnly` properties are heavily used

---

## `--validation` (Deprecated)

!!! warning "Deprecated"
    Use `--field-constraints` instead. The `--validation` option is maintained for backward compatibility.

Enables validation constraints from OpenAPI schemas.

```bash
# Deprecated
datamodel-codegen --input openapi.yaml --output models.py --validation

# Recommended
datamodel-codegen --input openapi.yaml --output models.py --field-constraints
```

See [Field Constraints](field-constraints.md) for details.

---

## Common Patterns

### Pattern 1: Basic API models

For simple APIs where you only need schema models:

```bash
datamodel-codegen --input openapi.yaml --output models.py
```

### Pattern 2: Full API client models

For generating complete models for an API client:

```bash
datamodel-codegen --input openapi.yaml --output models/ \
  --openapi-scopes schemas parameters paths \
  --use-operation-id-as-name \
  --include-path-parameters
```

### Pattern 3: Strict request/response separation

For APIs with distinct input/output shapes:

```bash
datamodel-codegen --input openapi.yaml --output models/ \
  --read-only-write-only-model-type request-response \
  --field-constraints
```

### Pattern 4: Versioned API structure

For large APIs with versioned endpoints:

```bash
datamodel-codegen --input openapi.yaml --output models/ \
  --treat-dot-as-module \
  --use-operation-id-as-name \
  --all-exports-scope recursive
```

---

## OpenAPI Version Support

| OpenAPI Version | Support |
|-----------------|---------|
| 3.0.x | Full support |
| 3.1.x | Full support |
| 3.2.x | Full support |
| 2.0 (Swagger) | Partial support |

---

## See Also

- [CLI Reference: OpenAPI-only Options](cli-reference/openapi-only-options.md)
- [Field Constraints](field-constraints.md)
- [Module Structure and Exports](module-exports.md)
- [OpenAPI Input Format](openapi.md)

---

# Generate from AsyncAPI

Source: https://datamodel-code-generator.koxudaxi.dev/asyncapi/

Generate Python models from AsyncAPI 2.x and 3.x documents.

!!! warning "Experimental"
    AsyncAPI input support is experimental and may change as real-world usage is validated.

## 🚀 Quick Start

```bash
datamodel-codegen \
    --input asyncapi.yaml \
    --input-file-type asyncapi \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

## 📝 Example

**asyncapi.yaml**
```yaml
asyncapi: 3.0.0
info:
  title: User events
  version: 1.0.0
channels:
  userSignedUp:
    messages:
      userSignedUp:
        payload:
          $ref: '#/components/schemas/UserSignedUp'
components:
  schemas:
    UserSignedUp:
      type: object
      required:
        - id
        - email
      properties:
        id:
          type: string
        email:
          type: string
          format: email
```

**✨ Generated model.py**
```python
from __future__ import annotations

from pydantic import BaseModel, EmailStr


class UserSignedUp(BaseModel):
    id: str
    email: EmailStr
```

## Supported AsyncAPI Versions

The AsyncAPI parser supports documents with `asyncapi` versions in the 2.x and 3.x families.

| Version | Schema behavior |
|---------|-----------------|
| 2.x | Message `schemaFormat` is applied to the message payload. AsyncAPI Schema Objects are handled with OpenAPI 3.0-compatible schema features. |
| 3.x | `payload`, `headers`, and `components.schemas` may be AsyncAPI Schema Objects, Reference Objects, or Multi Format Schema Objects. AsyncAPI Schema Objects are handled with OpenAPI 3.1-compatible schema features. |

Use `--schema-version auto` to detect the version from the `asyncapi` field, or pass
`--schema-version 2.0` / `--schema-version 3.0` to select a version explicitly.

## Model Generation Scope

datamodel-code-generator generates data models from schema-bearing fields. It does not generate clients, servers, protocol adapters, or runtime message validators.

The AsyncAPI parser extracts schemas from:

| AsyncAPI location | Generated models |
|-------------------|------------------|
| `components.schemas` | Reusable schema models |
| `components.messages[*].payload` and `headers` | Reusable message payload/header models |
| `components.messages[*].bindings` | Binding schemas for schema-bearing binding fields such as Kafka `key` and HTTP `headers` |
| `channels[*].publish.message`, `subscribe.message`, and `messages[*]` | Channel message payload/header models |
| `channels[*].parameters[*].schema` and `components.parameters[*].schema` | Channel parameter schema models |
| `channels[*].bindings` and `components.channels[*].bindings` | Binding schemas for schema-bearing binding fields such as WebSockets `query`/`headers` |
| `operations[*].messages` and `operations[*].reply.messages` | Operation request/reply message payload/header models |
| `components.operations[*].messages` and `reply.messages` | Reusable operation message payload/header models |
| `operations[*].bindings` and `components.operations[*].bindings` | Binding schemas for schema-bearing binding fields such as HTTP `query` and Kafka `groupId`/`clientId` |
| `components.replies[*].messages` | Reusable reply message payload/header models |
| `message.traits[*].headers` and `components.messageTraits[*].headers` | Header models when the message itself does not define `headers` |
| `message.traits[*].bindings` and `components.messageTraits[*].bindings` | Binding schemas supplied by message traits |
| `operation.traits[*].bindings` and `components.operationTraits[*].bindings` | Binding schemas supplied by operation traits |
| Local and external Reference Objects | Resolved before model generation |

Protocol binding configuration is treated as transport metadata unless the AsyncAPI binding
specification defines the field as a Schema Object or Reference Object. The parser currently
generates models for the schema-bearing binding fields used by the official bindings, including
`headers`, `query`, `key`, `groupId`, and `clientId`.

## Schema Formats

AsyncAPI 3.x Multi Format Schema Objects are unwrapped through `schemaFormat` before model generation.
AsyncAPI 2.x message-level `schemaFormat` is applied to the message payload.

Supported embedded schema formats are:

| `schemaFormat` family | Behavior |
|-----------------------|----------|
| `application/vnd.aai.asyncapi...` or omitted | Parsed as an AsyncAPI Schema Object |
| `application/schema+json` / `application/schema+yaml` | Parsed with the JSON Schema/OpenAPI schema stack |
| `application/vnd.oai.openapi...` | Parsed with the OpenAPI schema stack |
| `application/vnd.apache.avro...` | Converted with the Avro parser, then generated as Python models |
| `application/vnd.google.protobuf` | Converted with the Protocol Buffers parser, then generated as Python models |
| `application/xml`, `text/xml`, `application/xsd+xml`, `application/xml+schema`, `application/xml-schema` | Converted with the XML Schema parser, then generated as Python models |

RAML and custom embedded `schemaFormat` values inside an AsyncAPI document are rejected with an explicit error instead of producing partial or misleading models.

Embedded Protocol Buffers schemas support inline `.proto` source strings and local imports resolved relative to the AsyncAPI document. Embedded XML Schema supports inline XSD strings and local `xs:include` / `xs:import` / `xs:redefine` / `xs:override` locations resolved relative to the AsyncAPI document.

## Limitations

The AsyncAPI input type is for model generation from message payloads, headers, and reusable schemas. It does not:

- validate complete AsyncAPI documents;
- apply protocol binding runtime semantics;
- generate producer/consumer code;
- enforce runtime message validation;
- merge multiple traits that define the same `headers` property.

## 📖 See Also

- 🖥️ [CLI Reference](cli-reference/index.md) - Complete CLI options reference
- 📋 [Generate from JSON Schema](jsonschema.md) - JSON Schema input documentation
- 📘 [Generate from OpenAPI](openapi.md) - OpenAPI schema behavior
- 🪶 [Generate from Apache Avro Schema](avro.md) - Avro schema input documentation

---

# Generate from JSON Schema

Source: https://datamodel-code-generator.koxudaxi.dev/jsonschema/

Generate Pydantic models from JSON Schema definitions. See [Supported Data Types](./supported-data-types.md#openapi-3-and-json-schema) for supported JSON Schema features.

## 🚀 Quick Start

```bash
datamodel-codegen \
    --input person.json \
    --input-file-type jsonschema \
    --output-model-type pydantic_v2.BaseModel \
    --use-annotated \
    --output model.py
```

## 📝 Example

**person.json**
```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Person",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string",
      "description": "The person's first name."
    },
    "lastName": {
      "type": "string",
      "description": "The person's last name."
    },
    "age": {
      "description": "Age in years which must be equal to or greater than zero.",
      "type": "integer",
      "minimum": 0
    },
    "friends": {
      "type": "array"
    },
    "comment": {
      "type": "null"
    }
  }
}
```


**✨ Generated model.py**
```python
# generated by datamodel-codegen:
#   filename:  person.json
#   timestamp: 2020-04-27T16:12:27+00:00

from __future__ import annotations

from typing import Annotated, Any

from pydantic import BaseModel, Field


class Person(BaseModel):
    firstName: Annotated[str | None, Field(description="The person's first name.")] = None
    lastName: Annotated[str | None, Field(description="The person's last name.")] = None
    age: Annotated[
        int | None,
        Field(
            description="Age in years which must be equal to or greater than zero.",
            ge=0,
        ),
    ] = None
    friends: list[Any] | None = None
    comment: Annotated[None, Field(None)] = None
```

## Tuple validation

JSON Schema's [`prefixItems`](https://json-schema.org/understanding-json-schema/reference/array.html#tuple-validation) syntax lets you describe heterogeneous arrays.

When:

- `prefixItems` is present
- no `items` are specified
- `minItems`/`maxItems` match the number of prefix entries

datamodel-code-generator emits precise tuple annotations.

### Example

```json
{
  "$defs": {
    "Span": {
      "type": "object",
      "properties": {
        "value": { "type": "integer" }
      },
      "required": ["value"]
    }
  },
  "title": "defaults",
  "type": "object",
  "properties": {
    "a": {
      "type": "array",
      "prefixItems": [
        { "$ref": "#/$defs/Span" },
        { "type": "string" }
      ],
      "minItems": 2,
      "maxItems": 2
    }
  },
  "required": ["a"]
}
```

```py
from pydantic import BaseModel


class Span(BaseModel):
    value: int


class Defaults(BaseModel):
    a: tuple[Span, str]
```

---

## Custom Base Class with `customBasePath`

You can specify custom base classes directly in your JSON Schema using the `customBasePath` extension. This allows you to define base classes at the schema level without using CLI options.

### Single Base Class

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "User",
  "type": "object",
  "customBasePath": "myapp.models.UserBase",
  "properties": {
    "name": {"type": "string"},
    "email": {"type": "string"}
  },
  "required": ["name", "email"]
}
```

**Generated Output:**

```python
from __future__ import annotations

from myapp.models import UserBase


class User(UserBase):
    name: str
    email: str
```

### Multiple Base Classes (Mixins)

You can also specify multiple base classes as a list to implement mixin patterns:

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "User",
  "type": "object",
  "customBasePath": ["mixins.AuditMixin", "mixins.TimestampMixin"],
  "properties": {
    "name": {"type": "string"},
    "email": {"type": "string"}
  },
  "required": ["name", "email"]
}
```

**Generated Output:**

```python
from __future__ import annotations

from mixins import AuditMixin, TimestampMixin


class User(AuditMixin, TimestampMixin):
    name: str
    email: str
```

!!! note "Mixin Usage"
    When using multiple base classes, the specified classes are used directly without adding `BaseModel`.
    Ensure your mixins inherit from `pydantic.BaseModel` if you need Pydantic model behavior.

### Priority Resolution

When multiple base class configurations are present, they are resolved in this order:

1. **`--base-class-map`** (CLI option) - Highest priority
2. **`customBasePath`** (JSON Schema extension)
3. **`--base-class`** (CLI option) - Lowest priority (default for all models)

This allows you to set a default base class with `--base-class`, override specific models in the schema with `customBasePath`, and further override at the CLI level with `--base-class-map`.

## Supported JSON Schema Features

| Feature | Generation behavior |
|---------|---------------------|
| Object properties and required fields | Generated as model fields |
| `$ref`, `$defs`, and `definitions` | Resolved before model generation |
| `oneOf`, `anyOf`, `allOf` | Converted into unions and composed models where possible |
| Scalar constraints | Generated as `Field(...)` metadata with `--field-constraints` / `--use-annotated` |
| `format` values | Mapped to Python/Pydantic types where supported |
| Custom extensions | `customBasePath` and related options can steer generated base classes |

## Regular Expression Patterns

Pydantic v2 validates `pattern` with pydantic-core's Rust regex engine by default, and pydantic-core compiles the
pattern when the model class is created. Some syntax that Python's `re` accepts is rejected by every
pydantic-core release, so a model that uses it fails at import. For Pydantic v2 output from JSON Schema and
OpenAPI, the generator detects this syntax statically and sets `regex_engine="python-re"` on the model that owns
the pattern. The decision depends only on the pattern text and `--target-python-version`. It does not depend on
the installed pydantic-core or on the Python running the generator, and it is the same for every
`--target-pydantic-version`. `regex_engine` needs Pydantic 2.5: on Pydantic 2.0 to 2.4 such a model fails at import
whatever the target. A pattern in a type alias has no model that owns it, so the alias carries a compiled pattern, or,
with `--target-pydantic-version 2`, every generated model that reaches the alias selects the engine (see
[Targeting a Pydantic version](output-model-types.md#targeting-a-pydantic-version)).

| Pattern syntax | Example | Generated model |
|----------------|---------|-----------------|
| Lookahead and lookbehind | `(?=x)`, `(?<!x)` | `python-re` |
| Numbered backreferences and octal escapes | `([a-z])\1`, `\0`, `[\101]` | `python-re` |
| Named backreferences | `(?P<c>x)(?P=c)` | `python-re` |
| Conditionals | `(<)?a(?(1)>)` | `python-re` |
| End of string | `\Z` | `python-re` |
| Comments | `(?#note)` | `python-re` |
| Named characters | `\N{LATIN SMALL LETTER A}` | `python-re` |
| Backspace in a character class | `[\b]` | `python-re` |
| ASCII flag | `(?a)`, `(?a:x)`, `(?ia)` | `python-re` |
| Braces that cannot start a counted repetition | `a{,3}`, `{[a-z]+}` | `python-re` |
| Atomic groups | `(?>a+)` | `python-re` with `--target-python-version` 3.11 or later; unchanged for 3.10 |
| Escaped characters and character class members | `\\1`, `\(\?>`, `[(?>{]` | Rust engine (default); the lookaround check still matches `(?=` and `(?<!` even when escaped or inside a class |
| Rust-only syntax | `a{2, 3}`, `\p{L}`, `\x{41}`, `\b{start}`, `[[a-z]{]`, `(?P<ids[]>x)` | Rust engine |
| Syntax both engines reject | `(?L)`, `([a-z])\1\p{L}` | `python-re`; still fails at import, with Python's error |
| Possessive quantifiers | `a++`, `a*+` | Rust engine; pydantic-core accepts them as nested repetitions |
| Syntax only Pydantic 2.0.0-2.0.2 rejects | `\/`, `\:`, `(?<name>x)`, `[a&&b]` | Rust engine |
| Patterns over Rust's compiled size limit | `[\w.-]{1,256}` | Rust engine; not detectable from the syntax |
| Verbose patterns | `(?x) a b` | Rust engine; the scan does not model verbose whitespace and comments |

Apart from the lookaround check, the scan follows the Rust grammar of every pydantic-core release from 2.3.0 on,
so a pattern pydantic-core accepts is never switched. A switched pattern that also contains syntax the target
Python's `re` does not parse keeps the default engine: possessive quantifiers need Python 3.11 and `\z` needs
Python 3.14. The generator does not compile the pattern with Python's `re`. Lookaround keeps its existing detection
for every field. The other rules apply only to patterns emitted for string fields, including unions of strings such
as `type: ["string", "null"]`: a `pattern` on `format: uri` (`AnyUrl`) is not emitted. A `pattern` on `bytes`
(`format: binary`) is written only with `--field-constraints` or `--use-annotated`. On plain and optional `bytes`
fields Pydantic 2.0 to 2.10 rejects any such pattern at import, Pydantic 2.11 to 2.13 ignores it, and Pydantic 2.14
compiles it like a string pattern, so the rules also apply to it with `--target-pydantic-version 2.14`. With an
unset or older target the model keeps the default engine for its other patterns, and a `bytes` pattern that the Rust
engine rejects fails at import on Pydantic 2.14. Pydantic 2.12 also compiles the pattern of a `bytes | MISSING`
field (`--use-missing-sentinel`), so such a pattern fails at import there too. A union that has a string member
beside `bytes`, such as `str | bytes`, follows the string rules for every target.
Because `regex_engine` is a model setting, every pattern in that model then uses Python's `re` semantics, for
example `$` also matches before a trailing newline. Python's `re` is a backtracking engine without the Rust engine's
linear-time guarantee: review such patterns, and bound input length (for example with `maxLength`) when they
validate untrusted input.

## Limitations

JSON Schema input generates Python model definitions. It does not perform runtime validation by itself, and some
schema keywords are represented as type hints or field metadata rather than full JSON Schema validator behavior. See
[Schema Version Support](supported_formats.md) for version-specific coverage.

---

## 📖 See Also

- 🚀 [Getting Started](getting-started.md) - Installation and first model
- 🖥️ [CLI Reference](cli-reference/index.md) - Complete CLI options reference
- 🔧 [CLI Reference: Typing Customization](cli-reference/typing-customization.md) - Type annotation options
- 🏷️ [CLI Reference: Field Customization](cli-reference/field-customization.md) - Field naming and constraint options
- 📊 [Supported Data Types](supported-data-types.md) - JSON Schema data type support
- 🏗️ [CLI Reference: Model Customization](cli-reference/model-customization.md) - Base class and model customization options

---

# Generate from Apache Avro Schema

Source: https://datamodel-code-generator.koxudaxi.dev/avro/

Generate Python models from JSON-encoded Apache Avro schemas (`.avsc`).

!!! warning "Experimental"
    Apache Avro schema input support is experimental and may change as real-world usage is validated.

## 🚀 Quick Start

```bash
datamodel-codegen \
    --input user.avsc \
    --input-file-type avro \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

## 📝 Example

**user.avsc**
```json
{
  "type": "record",
  "name": "User",
  "namespace": "example.avro",
  "doc": "A user record.",
  "fields": [
    {
      "name": "id",
      "type": {
        "type": "string",
        "logicalType": "uuid"
      }
    },
    {
      "name": "name",
      "type": "string",
      "doc": "Display name"
    },
    {
      "name": "email",
      "type": ["null", "string"],
      "default": null
    },
    {
      "name": "roles",
      "type": {
        "type": "array",
        "items": {
          "type": "enum",
          "name": "Role",
          "symbols": ["admin", "member"]
        }
      },
      "default": []
    }
  ]
}
```

**✨ Generated model.py**
```python
from __future__ import annotations

from enum import Enum
from typing import Optional
from uuid import UUID

from pydantic import BaseModel, Field


class Role(Enum):
    admin = "admin"
    member = "member"


class User(BaseModel):
    id: UUID
    name: str = Field(..., description="Display name")
    email: Optional[str] = None
    roles: list[Role] = []
```

## Supported Avro Schema Features

The Avro parser supports the schema constructs needed to generate Python models:

| Avro construct | Model generation behavior |
|----------------|---------------------------|
| `record` | Generates a Python model class with fields |
| `enum` | Generates an enum class |
| `array` | Generates a list field or root list model |
| `map` | Generates a dict field or root dict model |
| `fixed` | Generates a fixed-length binary string model |
| `union` | Generates union types; nullable unions such as `["null", "string"]` become optional fields |
| Named types | Resolves `name`, `namespace`, fullnames, nested named types, and references |
| Field metadata | Preserves `doc`, `default`, `aliases`, and `order` where applicable |
| Logical types | Maps Avro logical types to Python-friendly formats where possible |

Supported primitive types are `null`, `boolean`, `int`, `long`, `float`, `double`, `bytes`, and `string`.

## Logical Types

Avro logical types are mapped through the generator's normal type handling:

| Avro logical type | Typical generated Python type |
|-------------------|-------------------------------|
| `decimal`, `big-decimal` | `Decimal` |
| `uuid` | `UUID` |
| `date` | `date` |
| `time-millis`, `time-micros` | `time` |
| `timestamp-millis`, `timestamp-micros`, `timestamp-nanos` | `datetime` |
| `local-timestamp-millis`, `local-timestamp-micros`, `local-timestamp-nanos` | local date-time format |
| `duration` | `timedelta` |

Generated temporal defaults use Avro's day, millisecond, microsecond, or nanosecond units. Timestamp defaults use UTC; local timestamp and time defaults have no timezone. Backends that map these formats to strings receive ISO strings. Defaults outside Python's date/time range, or nanosecond defaults that cannot be represented exactly at microsecond precision, produce an error.

Decimal defaults decode the bytes or fixed value as a signed big-endian integer and apply the declared scale exactly. Generated `Decimal` values preserve trailing zeros and do not depend on the active decimal context's precision. A scale outside Python's Decimal range produces an error.

Duration defaults with zero months and zero days preserve the milliseconds component as `timedelta`. Nonzero calendar components produce an error because their meaning depends on the calendar and cannot be represented exactly by `timedelta`. Encoded duration defaults must contain exactly 12 bytes.

Avro-specific metadata is preserved in generated JSON Schema extensions such as `x-avro-fullname`, `x-avro-namespace`, `x-avro-aliases`, and `x-avro-logicalType` before model generation.

## Schema Version

Apache Avro schemas do not include an in-schema version marker equivalent to JSON Schema's `$schema`, OpenAPI's `openapi`, or XML Schema versioning attributes. For that reason, `--schema-version` does not select an Avro specification version. The Avro parser follows the currently implemented Apache Avro schema rules and logical types.

## Limitations

datamodel-code-generator uses Avro schemas to generate Python model definitions. It does not implement Avro runtime validation, binary encoding, decoding, or serialization.

## 📖 See Also

- 🖥️ [CLI Reference](cli-reference/index.md) - Complete CLI options reference
- 📊 [Supported Data Types](supported-data-types.md) - Data type support details
- 📋 [Generate from JSON Schema](jsonschema.md) - JSON Schema input documentation

---

# Generate from XML Schema

Source: https://datamodel-code-generator.koxudaxi.dev/xmlschema/

Generate Python models from W3C XML Schema documents (`.xsd`).

!!! warning "Experimental"
    XML Schema input support is experimental and may change as real-world usage is validated.

## 🚀 Quick Start

```bash
datamodel-codegen \
    --input purchase_order.xsd \
    --input-file-type xmlschema \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

## 📝 Example

**purchase_order.xsd**
```xml
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="purchaseOrder" type="PurchaseOrder"/>

  <xs:complexType name="PurchaseOrder">
    <xs:sequence>
      <xs:element name="id" type="xs:string"/>
      <xs:element name="total" type="xs:decimal"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>
```

**✨ Generated model.py**
```python
from __future__ import annotations

from decimal import Decimal

from pydantic import BaseModel


class PurchaseOrder(BaseModel):
    id: str
    total: Decimal
```

## Supported XML Schema Versions

The XML Schema parser supports XML Schema 1.0 and selected XML Schema 1.1 constructs.
Use `--schema-version auto` to detect the version from versioning attributes and XSD
1.1 constructs, or pass `--schema-version 1.0` / `--schema-version 1.1` explicitly.

## Supported XML Schema Features

The XML Schema parser converts XSD into the JSON Schema shape used by the normal
model-generation pipeline. It supports the constructs needed to generate Python
model definitions:

| XSD construct | Model generation behavior |
|---------------|---------------------------|
| Built-in simple types | Maps XML Schema scalar types to Python scalar types |
| `xs:complexType` | Generates a Python model class |
| `xs:simpleType` restrictions | Generates constrained scalar fields where possible |
| `xs:sequence`, `xs:choice`, `xs:all` | Generates fields from model particles |
| `minOccurs`, `maxOccurs`, `nillable` | Preserves optionality, lists, and nullability |
| Attributes | Generates model fields for XML attributes |
| `xs:include`, `xs:import`, `xs:redefine`, `xs:override` | Resolves local schema composition |
| Namespaces | Uses namespace context to avoid name collisions |
| Substitution groups and wildcards | Generates compatible model shapes where possible |

## Limitations

The XML Schema input type is for generating Python model definitions. It does not
implement XML parsing, XML serialization, or runtime XML validation.

Generated Pydantic v2 `pattern` constraints that combine distinct facets in the same
restriction, or inherited and derived facets, require **Pydantic 2.8 or later in
the environment that runs the generated code**, for every `--target-pydantic-version`
including `2`. These constraints use compiled
Python regular expressions to preserve full-value matching and inherited restrictions,
including when a generated type alias is used directly with `TypeAdapter`.
[Pydantic 2.8 added support for compiled patterns](https://pydantic.dev/articles/pydantic-v2-8-release#respect-regex-flags-in-constrained-string-validation).
This does not add generated validators or change the Pydantic requirement for other
XSD inputs or input formats. Upgrading only the environment that runs
datamodel-code-generator does not upgrade the generated code's runtime.

Python properties use XML local names. Generation fails when distinct XML names
would overwrite the same property, such as an element and attribute named `code`,
or elements named `code` in different namespaces. Repeated uses of the same XML
name remain supported.

## 📖 See Also

- 🖥️ [CLI Reference](cli-reference/index.md) - Complete CLI options reference
- 📊 [Supported Data Types](supported-data-types.md) - Data type support details
- 📋 [Generate from JSON Schema](jsonschema.md) - JSON Schema input documentation

---

# Generate from Protocol Buffers / gRPC

Source: https://datamodel-code-generator.koxudaxi.dev/protobuf/

Generate Python models from Protocol Buffers schema files (`.proto`), including message types referenced by gRPC service definitions.

!!! warning "Experimental"
    Protocol Buffers input support is experimental and may change as real-world usage is validated.

## 🚀 Quick Start

Install the Protocol Buffers parser extra:

```bash
pip install 'datamodel-code-generator[protobuf]'
```

Generate models from a `.proto` file:

```bash
datamodel-codegen \
    --input order.proto \
    --input-file-type protobuf \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

## 📝 Example

**order.proto**
```proto
syntax = "proto3";

package example.shop.v1;

import "google/protobuf/timestamp.proto";

message Order {
  // Unique order identifier.
  string id = 1;
  repeated string tags = 2;
  google.protobuf.Timestamp created_at = 3;

  oneof contact {
    string email = 4;
    string phone = 5;
  }
}

message GetOrderRequest {
  string id = 1;
}

message GetOrderResponse {
  Order order = 1;
}

service OrderService {
  rpc GetOrder(GetOrderRequest) returns (GetOrderResponse);
}
```

**✨ Generated model.py**
```python
from __future__ import annotations

from pydantic import AwareDatetime, BaseModel, Field


class ExampleShopV1Order(BaseModel):
    id: str | None = Field("", description="Unique order identifier.")
    tags: list[str] | None = []
    created_at: AwareDatetime | None = None
    email: str | None = Field(None, description="oneof: contact")
    phone: str | None = Field(None, description="oneof: contact")


class ExampleShopV1GetOrderRequest(BaseModel):
    id: str | None = ""


class ExampleShopV1GetOrderResponse(BaseModel):
    order: ExampleShopV1Order | None = None
```

## Supported Protocol Buffers Features

The Protocol Buffers parser supports the schema constructs needed to generate Python model definitions:

| Protobuf construct | Model generation behavior |
|--------------------|---------------------------|
| Scalar fields | Maps protobuf scalar types to Python scalar types |
| `message` | Generates a Python model class |
| Nested `message` | Generates a named Python model class with package and parent context |
| `enum` | Generates an enum class |
| `repeated` | Generates a list field |
| `map<K, T>` | Generates a dict field for protobuf-supported string, integer, and bool key types |
| `oneof` | Generates nullable fields and preserves oneof membership as field metadata |
| `optional`, `required`, singular | Preserves proto2/proto3 presence and requiredness where model generation can represent it |
| Defaults | Preserves explicit proto2 defaults and proto3 implicit defaults |
| Package names | Included in generated class names to avoid cross-file collisions |
| Imports | Resolves regular imports, public imports, weak imports, fully-qualified type references, and cross-file references |
| Services and RPCs | Keeps request and response message types reachable for unary and streaming RPCs |
| Comments | Preserved as field descriptions when field descriptions are enabled |

Supported scalar types are `double`, `float`, `int32`, `int64`, `uint32`, `uint64`, `sint32`, `sint64`, `fixed32`, `fixed64`, `sfixed32`, `sfixed64`, `bool`, `string`, and `bytes`.

## Well-Known Types

Common `google.protobuf` well-known types are mapped through the generator's normal type handling:

| Protobuf type | Typical generated Python type |
|---------------|-------------------------------|
| `Timestamp` | `AwareDatetime` |
| `Duration` | `timedelta` |
| `Struct` | `dict[str, Any]` |
| `Value` | `bool | float | str | dict[str, Any] | list[Any] | None` |
| `ListValue` | `list[Any]` |
| `Any` | `dict[str, Any]` |
| `FieldMask` | `str` |
| Wrapper types | Optional scalar fields |

Referenced standard types without a built-in mapping are generated from their
compiled descriptors; unrelated standard types remain omitted. This includes the
`NullValue` enum, represented by its `NULL_VALUE` member like other generated enums.
This enum representation does not implement ProtoJSON's special `null` serialization;
acceptance of `None` follows the selected output backend.

## Schema Version

Protocol Buffers syntax is detected from each compiled `.proto` descriptor:

- `syntax = "proto3";` -> proto3
- `syntax = "proto2";` or no syntax declaration -> proto2
- `edition = "2023";` -> edition 2023

Use `--schema-version proto2`, `--schema-version proto3`, or `--schema-version 2023` to override
auto-detection when needed.

## Multiple Files

Pass a directory as input to generate from a group of related `.proto` files:

```bash
datamodel-codegen \
    --input ./protos \
    --input-file-type protobuf \
    --output ./models \
    --module-split-mode single
```

The parser resolves imports relative to the input file or directory and emits importable Python modules when an output directory is used.

## Limitations

datamodel-code-generator uses Protocol Buffers schemas to generate Python model definitions. It does not implement protobuf runtime validation, oneof runtime exclusivity checks, wire serialization, or gRPC client/server code generation.

Some protobuf constructs are parsed only as needed for data model generation. Options, custom options, extensions, reserved declarations, and service streaming markers are tolerated where possible but are not emitted as runtime protobuf behavior.

## 📖 See Also

- 🖥️ [CLI Reference](cli-reference/index.md) - Complete CLI options reference
- 📊 [Supported Data Types](supported-data-types.md) - Data type support details
- 📋 [Generate from JSON Schema](jsonschema.md) - JSON Schema input documentation

---

# Generate from MCP Tool Schemas

Source: https://datamodel-code-generator.koxudaxi.dev/mcp-tools/

Generate Python models from Model Context Protocol (MCP) tool schema profiles.

!!! warning "Experimental"
    MCP tool schema profile input support is experimental. The MCP specification and real-world tool schema shapes may
    evolve, so generated behavior may change as compatibility is expanded.

## Quick Start

```bash
datamodel-codegen \
    --input tools-list.json \
    --input-file-type mcp-tools \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

## Supported Input Shapes

The `mcp-tools` input type accepts:

- a `tools/list` JSON-RPC response containing `result.tools`;
- an MCP server definition containing a top-level `tools` array;
- a single tool definition or an array of tool definitions;
- JSON Schema documents whose `$defs` or `definitions` values are tool definitions.

Each tool must define `name` and `inputSchema`. If `outputSchema` is present, it is generated too.

## Example

**tools-list.json**
```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "search",
        "inputSchema": {
          "type": "object",
          "properties": {
            "query": { "type": "string" }
          },
          "required": ["query"]
        },
        "outputSchema": {
          "type": "object",
          "properties": {
            "results": {
              "type": "array",
              "items": { "type": "string" }
            }
          },
          "required": ["results"]
        }
      }
    ]
  }
}
```

**Generated model.py**
```python
from __future__ import annotations

from pydantic import BaseModel


class SearchInput(BaseModel):
    query: str


class SearchOutput(BaseModel):
    results: list[str]
```

## Naming

Tool names are converted to PascalCase and suffixed with `Input` or `Output`.

For example:

| Tool name | Generated input model | Generated output model |
|-----------|-----------------------|------------------------|
| `search` | `SearchInput` | `SearchOutput` |
| `create_issue` | `CreateIssueInput` | `CreateIssueOutput` |

## Notes

MCP `inputSchema` and `outputSchema` entries are converted into JSON Schema definitions before generation. Local
`$defs` and `definitions` entries inside a tool schema are hoisted and prefixed to avoid collisions between tools.

## Supported MCP Features

| Feature | Generation behavior |
|---------|---------------------|
| Tool `inputSchema` | Generated as `<ToolName>Input` |
| Tool `outputSchema` | Generated as `<ToolName>Output` when present |
| `tools/list` responses | Extracts `result.tools` |
| Server definitions | Extracts top-level `tools` arrays |
| Local `$defs` / `definitions` | Hoisted into generated JSON Schema definitions |

## Limitations

MCP tool schema input generates Python models from declared JSON Schemas. It does not connect to MCP servers, call
tools, validate tool runtime behavior, or infer schemas from tool implementations.

## See Also

- [Getting Started](getting-started.md)
- [MCP Tools specification](https://modelcontextprotocol.io/specification/2025-06-18/server/tools)
- [MCP Schema reference](https://modelcontextprotocol.io/specification/2025-06-18/schema)
- [Generate from JSON Schema](jsonschema.md)

---

# Generate from JSON / YAML / CSV Data

Source: https://datamodel-code-generator.koxudaxi.dev/jsondata/

Generate Pydantic models directly from raw JSON, YAML, or CSV data. Under the hood, the generator uses [GenSON](https://pypi.org/project/genson/) to infer a JSON Schema from JSON/YAML input, or infers a schema from CSV rows, then processes it the same way as [JSON Schema input](./jsonschema.md).

## 🚀 Quick Start

```bash
datamodel-codegen \
    --input pets.json \
    --input-file-type json \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

Use `--input-file-type yaml` for raw YAML sample data and `--input-file-type csv`
for CSV files. If a YAML file is a schema definition rather than sample data, use
`--input-file-type jsonschema`, `openapi`, or `asyncapi` instead.

## 📝 Example

**pets.json**
```json
{
  "pets": [
    {
      "name": "dog",
      "age": 2
    },
    {
      "name": "cat",
      "age": 1
    },
    {
      "name": "snake",
      "age": 3,
      "nickname": "python"
    }
  ],
  "status": 200
}
```


**✨ Generated model.py**
```python
# generated by datamodel-codegen:
#   filename:  pets.json
#   timestamp: 2020-04-27T16:08:21+00:00

from __future__ import annotations

from pydantic import BaseModel


class Pet(BaseModel):
    name: str
    age: int
    nickname: str | None = None


class Model(BaseModel):
    pets: list[Pet]
    status: int
```

## Supported Input Shapes

| Input type | Generation behavior |
|------------|---------------------|
| JSON object/array samples | Infers JSON Schema with GenSON, then generates models |
| YAML sample data | Parsed as sample data, then inferred like JSON |
| CSV files | Infers columns from rows and generates a tabular model |

## Limitations

Raw data input is inference-based. Optionality, unions, numeric ranges, and exact constraints depend on the sample
values you provide, so small or incomplete samples may produce broader models than a hand-authored schema.

---

## 📖 See Also

- 🚀 [Getting Started](getting-started.md) - Installation and first model
- 📋 [Generate from JSON Schema](jsonschema.md) - JSON Schema input documentation
- 🖥️ [CLI Reference](cli-reference/index.md) - Complete CLI options reference
- 📊 [Supported Data Types](supported-data-types.md) - Data type support details

---

# Generate from GraphQL

Source: https://datamodel-code-generator.koxudaxi.dev/graphql/

Generate Pydantic models from GraphQL schema definitions.

## 🚀 Quick Start

```bash
datamodel-codegen \
    --input schema.graphql \
    --input-file-type graphql \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

!!! tip "Default output model"
    When `--output-model-type` is omitted, datamodel-code-generator generates Pydantic v2 BaseModel output
    (`pydantic_v2.BaseModel`). Pass `--output-model-type` explicitly when you want another model family.

!!! note "📦 Installation"
    GraphQL support requires the `graphql` extra:
    ```bash
    pip install 'datamodel-code-generator[graphql]'
    ```

## 📝 Simple Example

Let's consider a simple GraphQL schema (more details in [GraphQL Schemas and Types](https://graphql.org/learn/schema/)).

**schema.graphql**
```graphql
type Book {
  id: ID!
  title: String
  author: Author
}

type Author {
  id: ID!
  name: String
  books: [Book]
}

input BooksInput {
    ids: [ID!]!
}

input AuthorBooksInput {
    id: ID!
}

type Query {
  getBooks(input: BooksInput): [Book]
  getAuthorBooks(input: AuthorBooksInput): [Book]
}
```

**✨ Generated model.py**
```python
# generated by datamodel-codegen:
#   filename:  schema.graphql
#   timestamp: 2023-11-20T17:04:42+00:00

from __future__ import annotations

from typing import TypeAlias

from pydantic import BaseModel, Field
from typing_extensions import Literal

# The `Boolean` scalar type represents `true` or `false`.
Boolean: TypeAlias = bool


# The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
ID: TypeAlias = str


# The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
String: TypeAlias = str


class Author(BaseModel):
    books: list[Book | None] | None = Field(default_factory=list)
    id: ID
    name: String | None = None
    typename__: Literal["Author"] | None = Field("Author", alias="__typename")


class Book(BaseModel):
    author: Author | None = None
    id: ID
    title: String | None = None
    typename__: Literal["Book"] | None = Field("Book", alias="__typename")


class AuthorBooksInput(BaseModel):
    id: ID
    typename__: Literal["AuthorBooksInput"] | None = Field("AuthorBooksInput", alias="__typename")


class BooksInput(BaseModel):
    ids: list[ID]
    typename__: Literal["BooksInput"] | None = Field("BooksInput", alias="__typename")
```

---

## 📤 Response Deserialization

For the following response of `getAuthorBooks` GraphQL query:

**response.json**
```json
{
  "getAuthorBooks": [
    {
      "author": {
        "id": "51341cdscwef14r13",
        "name": "J. K. Rowling"
      },
      "id": "1321dfvrt211wdw",
      "title": "Harry Potter and the Prisoner of Azkaban"
    },
    {
      "author": {
        "id": "51341cdscwef14r13",
        "name": "J. K. Rowling"
      },
      "id": "dvsmu12e19xmqacqw9",
      "title": "Fantastic Beasts: The Crimes of Grindelwald"
    }
  ]
}
```

**main.py**
```python
from model import Book

response = {...}

books = [Book.model_validate(book_raw) for book_raw in response["getAuthorBooks"]]
print(books)
# [Book(author=Author(books=[], id='51341cdscwef14r13', name='J. K. Rowling', typename__='Author'), id='1321dfvrt211wdw', title='Harry Potter and the Prisoner of Azkaban', typename__='Book'), Book(author=Author(books=[], id='51341cdscwef14r13', name='J. K. Rowling', typename__='Author'), id='dvsmu12e19xmqacqw9', title='Fantastic Beasts: The Crimes of Grindelwald', typename__='Book')]
```

---

## 🎨 Custom Scalar Types

```bash
datamodel-codegen \
    --input schema.graphql \
    --input-file-type graphql \
    --output-model-type pydantic_v2.BaseModel \
    --extra-template-data data.json \
    --output model.py
```

**schema.graphql**
```graphql
scalar Long

type A {
  id: ID!
  duration: Long!
}
```

**data.json**
```json
{
  "Long": {
    "py_type": "int"
  }
}
```

**✨ Generated model.py**
```python
# generated by datamodel-codegen:
#   filename:  custom-scalar-types.graphql
#   timestamp: 2019-07-26T00:00:00+00:00

from __future__ import annotations

from typing import Optional, TypeAlias

from pydantic import BaseModel, Field
from typing_extensions import Literal

# The `Boolean` scalar type represents `true` or `false`.
Boolean: TypeAlias = bool


# The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
ID: TypeAlias = str


Long: TypeAlias = int


# The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
String: TypeAlias = str


class A(BaseModel):
    duration: Long
    id: ID
    typename__: Optional[Literal["A"]] = Field("A", alias="__typename")
```

---

## 🚫 Excluding __typename Field

When using generated models for GraphQL mutations, the `__typename` field may cause issues
as GraphQL servers typically don't expect this field in input data.

Use the `--graphql-no-typename` option to exclude this field:

```bash
datamodel-codegen \
    --input schema.graphql \
    --input-file-type graphql \
    --output-model-type pydantic_v2.BaseModel \
    --graphql-no-typename \
    --output model.py
```

**Before (default):**
```python
class Book(BaseModel):
    id: ID
    title: String | None = None
    typename__: Literal["Book"] | None = Field("Book", alias="__typename")
```

**After (with --graphql-no-typename):**
```python
class Book(BaseModel):
    id: ID
    title: String | None = None
```

!!! warning "Union Type Discrimination"
    If your schema uses GraphQL union types and you rely on `__typename` for type
    discrimination during deserialization, excluding this field may break that functionality.
    Consider using this option only for input types or schemas without unions.

## Supported GraphQL Features

| Feature | Generation behavior |
|---------|---------------------|
| Object and input object types | Generated as model classes |
| Enums | Generated as Python enum types |
| Scalars | Built-in scalars map to Python aliases; custom scalars can be configured |
| Lists and non-null markers | Converted into Python collection and optionality annotations |
| `__typename` | Included by default and removable with `--graphql-no-typename` |

## Limitations

GraphQL input generates data models from schema definitions. It does not generate query builders, clients, resolvers,
schema execution code, or runtime GraphQL validation.

---

## 📖 See Also

- 🚀 [Getting Started](getting-started.md) - Installation and first model
- 🖥️ [CLI Reference](cli-reference/index.md) - Complete CLI options reference
- 🔧 [CLI Reference: Typing Customization](cli-reference/typing-customization.md) - Type annotation options
- 🎨 [CLI Reference: `--extra-template-data`](cli-reference/template-customization.md#extra-template-data) - Custom scalar type mappings

---

# Generate from Python Models

Source: https://datamodel-code-generator.koxudaxi.dev/python-model/

Generate code from existing Python types: Pydantic models, dataclasses, TypedDict, or dict schemas. This is useful for converting between model types or generating from programmatically-defined schemas.

## 🚀 Quick Start {#quick-start}

```bash
datamodel-codegen --input-model ./mymodule.py:User --output model.py
```

## 🔄 Convert Between Python Model Styles {#convert-between-python-model-styles}

`--input-model` can retarget an existing Python model into another supported output model type. This is useful when
moving a codebase between model frameworks, or when one boundary needs validation models while another boundary needs
plain typed dictionaries.

```bash
# Pydantic BaseModel -> TypedDict
datamodel-codegen \
  --input-model ./models.py:User \
  --output-model-type typing.TypedDict \
  --output user_types.py

# TypedDict -> Pydantic v2
datamodel-codegen \
  --input-model ./types.py:User \
  --output-model-type pydantic_v2.BaseModel \
  --output user_model.py
```

## Format {#format}

```
--input-model <path/to/file.py>:<ObjectName>
```

Simply specify the **file path** and **object name** separated by `:`.

### Example {#format-example}

```
myproject/
├── src/
│   └── models/
│       └── user.py      # class User(BaseModel): ...
└── schemas.py           # USER_SCHEMA = {...}
```

```bash
# From file path (recommended - easy to copy-paste)
datamodel-codegen --input-model src/models/user.py:User --output model.py
datamodel-codegen --input-model ./schemas.py:USER_SCHEMA --input-file-type jsonschema

# Windows paths also work
datamodel-codegen --input-model src\models\user.py:User
```

!!! tip "Copy-paste friendly"
    Just copy the file path from your editor or file explorer, add `:ClassName`, and you're done!

### Module format (alternative) {#module-format}

You can also use Python module notation with dots:

```bash
datamodel-codegen --input-model src.models.user:User
datamodel-codegen --input-model schemas:USER_SCHEMA --input-file-type jsonschema
```

!!! note "Current directory is auto-added to `sys.path`"
    No `PYTHONPATH` configuration needed.

!!! tip "File and package name conflict"
    If both `mymodule.py` and `mymodule/` directory exist, use `./` prefix:
    ```bash
    datamodel-codegen --input-model ./mymodule.py:Model
    ```

---

## Supported Input Types {#supported-input-types}

| Type | Description | Requires |
|------|-------------|----------|
| Pydantic BaseModel | Pydantic v2 models with `model_json_schema()` | Pydantic v2 |
| dataclass | Standard library `@dataclass` | Pydantic v2 (for TypeAdapter) |
| Pydantic dataclass | `@pydantic.dataclasses.dataclass` | Pydantic v2 |
| TypedDict | `typing.TypedDict` subclasses | Pydantic v2 (for TypeAdapter) |
| dict | Dict containing JSON Schema or OpenAPI spec | - |

!!! note "Pydantic v2 Required"
    All Python type inputs (except raw dict) require Pydantic v2 runtime to convert to JSON Schema.

---

## 📝 Examples {#examples}

### Pydantic BaseModel {#pydantic-basemodel}

**mymodule.py**
```python
from pydantic import BaseModel


class User(BaseModel):
    name: str
    age: int
```

```bash
datamodel-codegen --input-model ./mymodule.py:User --output model.py
```

**✨ Generated model.py**
```python
from __future__ import annotations

from pydantic import BaseModel


class User(BaseModel):
    name: str
    age: int
```

### Convert Pydantic to TypedDict {#convert-pydantic-to-typeddict}

```bash
datamodel-codegen --input-model ./mymodule.py:User --output-model-type typing.TypedDict --output model.py
```

**✨ Generated model.py**
```python
from __future__ import annotations

from typing import TypedDict


class User(TypedDict):
    name: str
    age: int
```

### Standard dataclass {#dataclass}

**mymodule.py**
```python
from dataclasses import dataclass


@dataclass
class User:
    name: str
    age: int
```

```bash
datamodel-codegen --input-model ./mymodule.py:User --output model.py
```

**✨ Generated model.py**
```python
from __future__ import annotations

from pydantic import BaseModel


class User(BaseModel):
    name: str
    age: int
```

### TypedDict {#typeddict}

**mymodule.py**
```python
from typing import TypedDict


class User(TypedDict):
    name: str
    age: int
```

```bash
datamodel-codegen --input-model ./mymodule.py:User --output model.py
```

**✨ Generated model.py**
```python
from __future__ import annotations

from pydantic import BaseModel, Field


class User(BaseModel):
    name: str = Field(..., title="Name")
    age: int = Field(..., title="Age")
```

### Dict Schema (JSON Schema) {#dict-jsonschema}

**mymodule.py**
```python
USER_SCHEMA = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer"},
    },
    "required": ["name", "age"],
}
```

```bash
datamodel-codegen --input-model ./mymodule.py:USER_SCHEMA --input-file-type jsonschema --output model.py
```

**✨ Generated model.py**
```python
from __future__ import annotations

from pydantic import BaseModel


class Model(BaseModel):
    name: str
    age: int
```

!!! warning "Dict requires --input-file-type"
    When using a dict schema, you must specify `--input-file-type` (e.g., `jsonschema`, `openapi`).

### Dict Schema (OpenAPI) {#dict-openapi}

**mymodule.py**
```python
OPENAPI_SPEC = {
    "openapi": "3.0.0",
    "info": {"title": "API", "version": "1.0.0"},
    "paths": {},
    "components": {
        "schemas": {
            "User": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                },
            }
        }
    },
}
```

```bash
datamodel-codegen --input-model ./mymodule.py:OPENAPI_SPEC --input-file-type openapi --output model.py
```

**✨ Generated model.py**
```python
from __future__ import annotations

from pydantic import BaseModel


class User(BaseModel):
    name: str | None = None
    age: int | None = None
```

---

## Custom Python Types with x-python-type {#x-python-type}

When using `x-python-type` in JSON Schema (via `WithJsonSchema` in Pydantic), the generator automatically resolves and generates the required imports.

### Automatic Import Resolution {#import-resolution}

The generator supports many common Python types out of the box:

| Module | Supported Types |
|--------|-----------------|
| `typing` | `Any`, `Union`, `Optional`, `Literal`, `Final`, `ClassVar`, `Annotated`, `TypeVar`, `TypeAlias`, `Never`, `NoReturn`, `Self`, `LiteralString`, `TypeGuard`, `Type` |
| `collections` | `defaultdict`, `OrderedDict`, `Counter`, `deque`, `ChainMap` |
| `collections.abc` | `Callable`, `Iterable`, `Iterator`, `Generator`, `Awaitable`, `Coroutine`, `AsyncIterable`, `AsyncIterator`, `AsyncGenerator`, `Mapping`, `MutableMapping`, `Sequence`, `MutableSequence`, `Set`, `MutableSet`, `Collection`, `Reversible` |
| `pathlib` | `Path`, `PurePath` |
| `decimal` | `Decimal` |
| `uuid` | `UUID` |
| `datetime` | `datetime`, `date`, `time`, `timedelta` |
| `enum` | `Enum`, `IntEnum`, `StrEnum`, `Flag`, `IntFlag` |
| `re` | `Pattern`, `Match` |

For types not in this list, the generator dynamically searches common modules to resolve imports.

### Example {#x-python-type-example}

**mymodule.py**
```python
from collections import defaultdict
from typing import Any, Annotated
from pydantic import BaseModel, Field, WithJsonSchema


class Config(BaseModel):
    data: (
        Annotated[
            defaultdict[str, Annotated[dict[str, Any], Field(default_factory=dict)]],
            WithJsonSchema({"type": "object", "x-python-type": "defaultdict[str, dict[str, Any]]"}),
        ]
        | None
    ) = None
```

```bash
datamodel-codegen --input-model ./mymodule.py:Config --output-model-type typing.TypedDict
```

**✨ Generated output**
```python
from __future__ import annotations

from collections import defaultdict
from typing import Any, TypedDict

from typing_extensions import NotRequired


class Config(TypedDict):
    data: NotRequired[defaultdict[str, dict[str, Any]] | None]
```

!!! tip "Fully Qualified Paths"
    You can also use fully qualified paths in `x-python-type` (e.g., `collections.defaultdict`), which are always resolved correctly regardless of the static mapping.

---

## Mutual Exclusion {#mutual-exclusion}

`--input-model` cannot be used with:

- `--input` (file input)
- `--url` (URL input)
- `--watch` (file watching)

## Supported Python Model Features {#supported-python-model-features}

| Input type | Generation behavior |
|------------|---------------------|
| Pydantic v2 `BaseModel` | Uses `model_json_schema()` |
| Standard dataclasses | Uses Pydantic TypeAdapter to derive schema |
| Pydantic dataclasses | Uses Pydantic schema support |
| TypedDict | Uses Pydantic TypeAdapter to derive schema |
| Dict schemas | Treated as JSON Schema or OpenAPI based on `--input-file-type` |

## Limitations {#limitations}

Python model input imports and evaluates the specified object, so the target module must be importable and safe to
import in your environment. Raw dict input requires `--input-file-type` because the generator cannot infer whether the
dict is JSON Schema, OpenAPI, or another schema profile.

---

## 📖 See Also

- 🚀 [Getting Started](getting-started.md) - Installation and first model
- 🖥️ [CLI Reference](cli-reference/index.md) - Complete CLI options reference
- 📁 [CLI Reference: Base Options](cli-reference/base-options.md#input-model) - `--input-model` option details
- 📋 [Generate from JSON Schema](jsonschema.md) - JSON Schema input documentation

---

# Output Model Types

Source: https://datamodel-code-generator.koxudaxi.dev/output-model-types/

<!-- related-cli-options: --output-model-type, --frozen-dataclasses, --keyword-only, --dataclass-arguments, --target-python-version -->

# Output Model Types

datamodel-code-generator supports multiple output model types. This page compares them to help you choose the right one for your project.

## Quick Comparison

| Model Type | Validation | Serialization | Performance | Use Case |
|------------|------------|---------------|-------------|----------|
| **Pydantic v2** | Runtime | Built-in | Fast | New projects, APIs, data validation |
| **Pydantic v2 dataclass** | Runtime | Built-in | Fast | Pydantic validation with dataclass syntax |
| **dataclasses** | None | Manual | Fastest | Simple data containers, no validation needed |
| **TypedDict** | Static only | Dict-compatible | N/A | Type hints for dicts, JSON APIs |
| **msgspec** | Runtime | Built-in | Fastest | High-performance serialization |

---

## Pydantic v2 (Recommended)

**Use `--output-model-type pydantic_v2.BaseModel`**

Pydantic v2 is recommended for new projects. It offers better performance and a modern API.

```bash
datamodel-codegen --input schema.json --output-model-type pydantic_v2.BaseModel --output model.py
```

```python
from pydantic import BaseModel, Field, RootModel


class Pet(BaseModel):
    id: int = Field(..., ge=0)
    name: str = Field(..., max_length=256)
    tag: str | None = None


class Pets(RootModel[list[Pet]]):
    root: list[Pet]
```

### When to use

- New projects requiring data validation
- APIs requiring data validation
- Projects needing JSON Schema generation from models

---

## Pydantic v2 dataclass

**Use `--output-model-type pydantic_v2.dataclass`**

Pydantic v2 dataclass combines the familiar dataclass syntax with Pydantic's validation capabilities.

```bash
datamodel-codegen --input schema.json --output-model-type pydantic_v2.dataclass --output model.py
```

```python
from pydantic.dataclasses import dataclass
from typing import Optional


@dataclass
class Pet:
    id: int
    name: str
    tag: Optional[str] = None
```

### When to use

- Want to use dataclass syntax with Pydantic validation
- Migrating from dataclasses but need validation
- Prefer decorator-based class definition

---

## Targeting a Pydantic version

Pydantic output depends only on the inputs and options, never on the Pydantic version installed next to
`datamodel-codegen`. Use `--target-pydantic-version` to choose the oldest Pydantic release the generated code must
run on. Pass `--target-pydantic-version 2` when the generated code must also run on older Pydantic 2 releases.

When the target is unset:

- **Feature forms** use the newest supported forms, the same as `2.12`.
- **Config key naming** is unchanged: `--allow-population-by-field-name` emits `populate_by_name=True`, as with `2`.
  Only an explicit `2.11`, `2.12` or `2.14` emits `validate_by_name=True`.
- **`--use-missing-sentinel`** keeps the experimental `pydantic.experimental.missing_sentinel` import, as with `2.12`.

| Generated form | `2` (Pydantic 2.0+) | Unset, `2.11`, `2.12`, `2.14` |
| --- | --- | --- |
| Constrained strings with `--use-annotated` (2.1+) | `Annotated[str, Field(...)]` | `Annotated[str, StringConstraints(...)]` |
| `pydantic_v2.dataclass` aliases that are not identifiers (2.4+) | `Field(validation_alias=..., serialization_alias=...)` assignment | `Field(alias=...)` |
| Deprecated fields (2.7+) | `Field(json_schema_extra={'deprecated': True})` | `Field(deprecated=True)` |
| Models used as dictionary keys (2.8+) | Defined before the models that use them as keys | Schema order |
| `--alias-generator` field aliases (2.8+) | `alias=` on every `BaseModel` field | `alias=` only where the generated alias differs |
| Type alias patterns that need Python's regex engine (2.8+) | String pattern; every model that reaches the alias, directly or through other models, sets `regex_engine="python-re"` | Compiled `re.compile(...)` pattern |
| `pydantic_v2.dataclass` aliases of other models (2.10+) | `Alias: TypeAlias = Model` | `Alias = TypeAliasType("Alias", Model)` |
| Explicit aliases naming a `BaseModel` attribute (2.10+) | Rejected when the attribute starts with `model_` | Rejected only when it starts with `model_validate` or `model_dump` |
| `--use-annotated` fields whose type is defined later in the module (2.11+) | `name: Type = Field(...)` assignment | `name: Annotated[Type, Field(...)]` |

| Config key naming | Unset, `2` | `2.11`, `2.12`, `2.14` |
| --- | --- | --- |
| `--allow-population-by-field-name` | `populate_by_name=True` | `validate_by_name=True` |

`2.12` also enables options that need Pydantic 2.12, such as `--use-missing-sentinel`.

| `--use-missing-sentinel` import | Unset, `2.12` | `2.14` |
| --- | --- | --- |
| `MISSING` (2.14 deprecates the experimental path) | `from pydantic.experimental.missing_sentinel import MISSING` | `from pydantic import MISSING` |

| `bytes` patterns the Rust regex engine rejects | Unset, `2`, `2.11`, `2.12` | `2.14` |
| --- | --- | --- |
| Model regex engine (2.14 compiles the patterns of plain and optional `bytes` fields, 2.11 to 2.13 ignore them) | Default engine | `regex_engine="python-re"` |

The `bytes` rule is not applied to an unset target, because `python-re` changes how the other patterns of the model
match on every Pydantic release. A `bytes` pattern with syntax such as a backreference then fails at import on
Pydantic 2.14 unless `--target-pydantic-version 2.14` is passed, and on Pydantic 2.12 for a `bytes | MISSING` field
(`--use-missing-sentinel`), whose pattern 2.12 compiles as well. Pydantic 2.0 to 2.10 rejects any rendered `bytes`
pattern at import. See [Regular Expression Patterns](jsonschema.md#regular-expression-patterns).

| `pydantic_v2.dataclass` required fields written as `= Field(...)` | Unset, `2`, `2.11`, `2.12` | `2.14` |
| --- | --- | --- |
| Position when the schema lists them after a field with a default of the same class (2.13+ rejects that order in `inspect.signature`) | Schema order | Before the fields with defaults |

A required `pydantic_v2.dataclass` field that needs `Field(...)`, for an alias, a description or a constraint, is
written as an assignment, so it can follow a field with a default:

```python
@dataclass
class Pet:
    plain: str
    nick: str | None = "x"
    first_name: str = Field(..., alias="first-name")
```

With the target unset or older than `2.14`, such a class keeps the order of datamodel-code-generator 0.83.0. It
validates and constructs on Pydantic 2.4 and later, the first release that accepts the non-identifier alias, but on
Pydantic 2.13 and later its signature cannot be read: `inspect.signature(Pet)` raises
`ValueError: non-default argument follows default argument`, which affects tools that read the signature. On Python
3.10 with Pydantic 2.13 and later, a dataclass that inherits from such a class fails at import with the same error,
because Python 3.10 reads the signature while it creates the subclass. Pass `--target-pydantic-version 2.14` in either
case: `first_name` is then written before `nick`. The generator warns about each class that keeps such an order, in its
own fields or through its bases.

The order is not changed for an unset or older target, because positional arguments follow the field order:
`Pet("p", "a", "b")` sets `nick="a"` in schema order and `first_name="a"` with `2.14`. Keyword arguments work with both
orders.

With `--use-annotated` a required field keeps its metadata in `Annotated` and comes before the fields with defaults on
every target. A non-identifier alias of such a field is written as an assignment with `2` (see the 2.4 row above); the
field then stays with the required fields, after those without an assignment. A required field that a subclass adds
after an inherited field with a default is written with `kw_only=True` for every target.

Patterns that need Python's regex engine, such as lookaround assertions (see
[Regular Expression Patterns](jsonschema.md#regular-expression-patterns)), rely on `regex_engine="python-re"`, which
Pydantic added in 2.5. With every target, a model that has such a pattern fails at import on Pydantic 2.0 to 2.4. A type
alias (`--use-type-alias`, and the root schemas of `pydantic_v2.dataclass` output) has no config of its own:

- With `2` its pattern stays a string, and every generated `BaseModel` or `pydantic_v2.dataclass` that reaches the
  alias, directly or through other models and their base classes, sets `regex_engine="python-re"`, so the generated
  models validate on Pydantic 2.5 and later. A `RootModel` that reaches the alias is written as `RootModel[Any]` and
  keeps the alias in its `root` annotation, because Pydantic builds the generic before the config applies.
- With `2`, nothing selects the engine outside the generated models. A hand-written model that embeds a generated model
  or alias must set `regex_engine="python-re"` itself, and an alias validated on its own needs
  `TypeAdapter(Alias, config=ConfigDict(regex_engine="python-re"))`. On Pydantic 2.8 to 2.10 this is a difference from
  an unset target, because no target lies between `2` and `2.11`.
- Unset, or with `2.11` and later, the alias carries a compiled `re.compile(...)` pattern, which needs Pydantic 2.8 and
  validates on its own.

The combined `pattern` constraints of XML Schema input stay compiled for every target, `2` included, and need Pydantic
2.8; see [XML Schema limitations](xmlschema.md#limitations).

With `2` and `--use-annotated`, a `BaseModel`, `RootModel` or `pydantic_v2.dataclass` field whose type names a model
defined later in the same module is written as an assignment, as it is without `--use-annotated`. Pydantic before 2.11
cannot evaluate such an annotation while it creates the class, and then mishandles the `Field()` inside
`Annotated[...]`: depending on the release it drops the alias and the description, ignores `validate_default`, or fails
on a constraint. Required dataclass fields written this way move after the other required fields. Fields that reference
only their own model or earlier models, and output without deferred annotations (`--disable-future-imports`), keep the
`Annotated` form.

For a field written this way, type checkers that read `Field()` assignments, such as pyright, take the alias as the
constructor argument name and treat a positional default such as `Field(None, alias=...)` as a required argument. Add
`--use-default-kwarg` to emit `Field(default=None, ...)` instead.

With `2`, `--alias-generator` output names every alias in `Field(alias=...)`. Type checkers that read the alias as the
constructor argument name, such as pyright, then expect the alias instead of the field name; at runtime
`populate_by_name=True` still accepts both.

---

## dataclasses

**Use `--output-model-type dataclasses.dataclass`**

Python's built-in dataclasses for simple data containers without runtime validation.

```bash
datamodel-codegen --input schema.json --output-model-type dataclasses.dataclass --output model.py
```

```python
from dataclasses import dataclass
from typing import Optional


@dataclass
class Pet:
    id: int
    name: str
    tag: Optional[str] = None
```

### Options for dataclasses

| Option | Description |
|--------|-------------|
| `--frozen-dataclasses` | Generate immutable dataclasses (`frozen=True`) |
| `--keyword-only` | Require keyword arguments (`kw_only=True`, Python 3.10+) |
| `--dataclass-arguments` | Custom decorator arguments as JSON |

```bash
# Frozen, keyword-only dataclasses
datamodel-codegen --input schema.json --output-model-type dataclasses.dataclass \
  --frozen-dataclasses --keyword-only --target-python-version 3.10
```

### When to use

- Simple data structures without validation needs
- Performance-critical code where validation overhead matters
- Interoperability with code expecting dataclasses

---

## TypedDict

**Use `--output-model-type typing.TypedDict`**

TypedDict provides static type checking for dictionary structures.

```bash
datamodel-codegen --input schema.json --output-model-type typing.TypedDict --output model.py
```

```python
from typing import TypedDict, NotRequired


class Pet(TypedDict):
    id: int
    name: str
    tag: NotRequired[str]
```

### When to use

- Working with JSON APIs where data remains as dicts
- Static type checking without runtime overhead
- Gradual typing of existing dict-based code

### Boundary payloads and partial updates

TypedDict is a good fit for data at an HTTP boundary. A PATCH payload can
distinguish three cases:

- the key is missing, so the existing value should stay unchanged
- the key is present with `null`, so the value should be cleared
- the key is present with a value, so the value should be replaced

Use `--strict-nullable` when the difference between a missing key and a
nullable value matters:

```bash
datamodel-codegen --input user-patch.schema.json \
  --output-model-type typing.TypedDict \
  --strict-nullable \
  --target-python-version 3.13 \
  --output model.py
```

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "UserPatch",
  "type": "object",
  "required": ["id"],
  "properties": {
    "id": {"type": "string", "readOnly": true},
    "nickname": {"type": ["string", "null"]},
    "bio": {"type": "string"}
  },
  "additionalProperties": false
}
```

```python
from typing import NotRequired
from typing_extensions import TypedDict


class UserPatch(TypedDict, closed=True):
    id: str
    nickname: NotRequired[str | None]
    bio: NotRequired[str]
```

Here `nickname: NotRequired[str | None]` means the key may be omitted, and
`None` is still a real value when the key is present. This follows
[PEP 655](https://peps.python.org/pep-0655/), which added `Required` and
`NotRequired` for per-key presence in TypedDict.

If the schema marks response-only fields with `readOnly`, combine this with
`--use-frozen-field` to generate `ReadOnly` for TypedDict output:

```bash
datamodel-codegen --input user-patch.schema.json \
  --output-model-type typing.TypedDict \
  --strict-nullable \
  --use-frozen-field \
  --target-python-version 3.13 \
  --output model.py
```

```python
from typing import NotRequired, ReadOnly
from typing_extensions import TypedDict


class UserPatch(TypedDict, closed=True):
    id: ReadOnly[str]
    nickname: NotRequired[str | None]
    bio: NotRequired[str]
```

`ReadOnly` comes from [PEP 705](https://peps.python.org/pep-0705/). The
`closed=True` output comes from [PEP 728](https://peps.python.org/pep-0728/)
and represents `additionalProperties: false` for type checkers that understand
closed TypedDicts.

!!! note "Background"
    The distinction between missing keys, `None`, and unset update arguments is
    covered in Koudai Aono's PyCon US 2026 talk
    [Beyond Optional in Real-World Projects](https://github.com/koxudaxi/pyconus_2026/blob/main/slides.md).
    In datamodel-code-generator today, TypedDict and msgspec preserve that
    boundary shape most directly. Pydantic models and dataclasses are usually a
    better fit after the boundary has been normalized into application data.

---

## msgspec

**Use `--output-model-type msgspec.Struct`**

[msgspec](https://github.com/jcrist/msgspec) offers high-performance serialization with validation.

```bash
pip install msgspec
datamodel-codegen --input schema.json --output-model-type msgspec.Struct --output model.py
```

```python
from msgspec import Struct, UNSET, UnsetType


class Pet(Struct):
    id: int
    name: str
    tag: str | UnsetType = UNSET
```

### Discriminated unions

msgspec only decodes a union of structs when every struct is tagged, and a tagged struct cannot also have a field
named like its `tag_field`. By default the output keeps the 0.83.0 form, in which a variant whose discriminator
value comes from the discriminator `mapping`, an `enum` or the schema name keeps the discriminator as a field:

```python
class Cat(Struct):
    petType: Literal["cat"]
    meow: str | UnsetType = UNSET
```

`Cat(petType='cat')`, `cat.petType` and decoding `Cat` on its own work, but decoding the union `Cat | Dog` raises
msgspec's `TypeError`. That form only tags a variant whose discriminator property is a single literal such as a
`const`, or one that a second discriminated union uses, and its `tag_field` is the generated field name, which
differs from the property name when the field is renamed.

[`--use-msgspec-tagged-unions`](cli-reference/model-customization.md#use-msgspec-tagged-unions) writes a union as
tagged structs as a whole instead, with the property name of the document as `tag_field`:

```python
class Cat(Struct, tag_field="petType", tag="cat"):
    meow: str | UnsetType = UNSET
```

The union then decodes, while `petType` is no longer a constructor argument or an attribute, and `Cat` decoded on
its own accepts a payload without `petType`. When a variant cannot take exactly one tag for the union, or a base
or derived struct of a variant keeps the property as a field, the union tags none of its variants, the ones with
a `const` included, and a warning names the reason. A variant that another union tags keeps that tag.

### Enums that list null

msgspec only decodes an `Enum` whose members are all `str` or all `int` values. By default the output keeps the
0.83.0 form of an enum that lists `null` without `type: string` or `nullable: true`, such as
`type: [integer, "null"]` with `enum: [1, 2, null]`, which is an Enum with a `None` member:

```python
class Size(Enum):
    int_1 = 1
    int_2 = 2
    NoneType_None = None
```

`Size.int_1` works, but decoding a struct with a `Size` field raises msgspec's `TypeError`, and the `IntEnum` that a
`type: integer` enum is written as fails at import.
[`--use-msgspec-nullable-enum-alias`](cli-reference/model-customization.md#use-msgspec-nullable-enum-alias) writes
it as a `type: string` or `nullable` enum is written instead, an Enum without the `None` member and an alias that
adds `None`:

```python
class SizeEnum(Enum):
    int_1 = 1
    int_2 = 2


Size: TypeAlias = SizeEnum | None
```

msgspec then decodes the members and `null`, while code that used `Size.int_1` or `Size.NoneType_None` uses
`SizeEnum.int_1` and `None`. The default of a field of such an enum is then its raw value, also with
`--set-default-enum-member`, and an enum that lists only `null` becomes `None`.

### When to use

- High-performance JSON/MessagePack serialization
- Memory-efficient data structures
- APIs with strict performance requirements

---

## Choosing the Right Type

```mermaid
graph TD
    A[Need runtime validation?] -->|Yes| B[Need best performance?]
    A -->|No| C[Need type hints for dicts?]
    B -->|Yes| D[msgspec.Struct]
    B -->|No| G[Prefer dataclass syntax?]
    G -->|Yes| H[pydantic_v2.dataclass]
    G -->|No| I[pydantic_v2.BaseModel]
    C -->|Yes| J[typing.TypedDict]
    C -->|No| K[dataclasses.dataclass]
```

### Decision Guide

1. **API with validation** → Pydantic v2
2. **Validation with dataclass syntax** → Pydantic v2 dataclass
3. **High-performance serialization** → msgspec
4. **Simple data containers** → dataclasses
5. **Dict-based JSON handling** → TypedDict

---

## See Also

- [CLI Reference: `--output-model-type`](cli-reference/model-customization.md#output-model-type)
- [CLI Reference: `--strict-nullable`](cli-reference/model-customization.md#strict-nullable)
- [CLI Reference: `--use-frozen-field`](cli-reference/model-customization.md#use-frozen-field)
- [CLI Reference: Model Customization](cli-reference/model-customization.md)
- [Pydantic Documentation](https://docs.pydantic.dev/)
- [msgspec Documentation](https://jcristharif.com/msgspec/)

---

# Model Reuse and Deduplication

Source: https://datamodel-code-generator.koxudaxi.dev/model-reuse/

<!-- related-cli-options: --reuse-model, --reuse-scope, --shared-module-name, --collapse-root-models, --disable-warnings, --use-type-alias -->

# Model Reuse and Deduplication

When generating models from schemas, you may encounter duplicate model definitions. datamodel-code-generator provides options to deduplicate models and share them across multiple files, improving output structure, reducing diff sizes, and enhancing performance.

## Quick Overview

| Option | Description |
|--------|-------------|
| `--reuse-model` | Deduplicate identical model/enum definitions |
| `--reuse-scope` | Control scope of deduplication (`root` or `tree`) |
| `--shared-module-name` | Name for shared module in multi-file output |
| `--collapse-root-models` | Inline root models instead of creating wrappers |
| `--use-type-alias` | Create TypeAlias for reusable field types (see [Reducing Duplicate Field Types](#reducing-duplicate-field-types)) |

---

## `--reuse-model`

The `--reuse-model` flag detects identical enum or model definitions and generates a single shared definition instead of duplicates.

### Without `--reuse-model`

```bash
datamodel-codegen --input schema.json --output model.py
```

```python
# Duplicate enums for animal and pet fields
class Animal(Enum):
    dog = "dog"
    cat = "cat"


class Pet(Enum):  # Duplicate!
    dog = "dog"
    cat = "cat"


class User(BaseModel):
    animal: Optional[Animal] = None
    pet: Optional[Pet] = None
```

### With `--reuse-model`

```bash
datamodel-codegen --input schema.json --output model.py --reuse-model
```

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: model-reuse.reuse-model.output -->
<!-- fmt: off -->

```python
from __future__ import annotations

from enum import Enum

from pydantic import BaseModel, Field, RootModel


class Animal(Enum):
    dog = 'dog'
    cat = 'cat'
    snake = 'snake'


class RedistributeEnum(Enum):
    static = 'static'
    connected = 'connected'


class User(BaseModel):
    name: str | None = None
    animal: Animal | None = 'dog'
    pet: Animal | None = 'cat'
    redistribute: list[RedistributeEnum] | None = None


class Redistribute(RootModel[list[RedistributeEnum]]):
    root: list[RedistributeEnum] = Field(
        ..., description='Redistribute type for routes.'
    )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: model-reuse.reuse-model.output -->

### Benefits

- **Smaller output** - Less generated code
- **Cleaner diffs** - Changes to shared types only appear once
- **Better performance** - Faster generation for large schemas
- **Type consistency** - Same types are truly the same

---

## `--reuse-scope`

Controls the scope for model reuse detection when processing multiple input files.

| Value | Description |
|-------|-------------|
| `root` | Detect duplicates only within each input file (default) |
| `tree` | Detect duplicates across all input files |

### Single-file input

For single-file input, `--reuse-scope` has no effect. Use `--reuse-model` alone.

### Multi-file input with `tree` scope

When generating from multiple schema files to a directory:

```bash
datamodel-codegen --input schemas/ --output models/ --reuse-model --reuse-scope tree
```

**Input files:**
```text
schemas/
├── user.json      # defines SharedModel
└── order.json     # also defines identical SharedModel
```

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: model-reuse.reuse-scope-tree.output -->
**Output with `--reuse-scope tree`:**

<!-- fmt: off -->

```text
models/
|-- __init__.py
|-- schema_a.py
|-- schema_b.py
`-- shared.py
```

<!-- fmt: on -->

**models/__init__.py:**
_No code beyond the generated header._

**models/schema_a.py:**

<!-- fmt: off -->

```python
from __future__ import annotations

from pydantic import BaseModel

from .shared import SharedModel as SharedModel_1


class SharedModel(SharedModel_1):
    pass


class Model(BaseModel):
    data: SharedModel | None = None
```

<!-- fmt: on -->

**models/schema_b.py:**

<!-- fmt: off -->

```python
from __future__ import annotations

from pydantic import BaseModel

from . import shared


class Model(BaseModel):
    info: shared.SharedModel | None = None
```

<!-- fmt: on -->

**models/shared.py:**

<!-- fmt: off -->

```python
from __future__ import annotations

from pydantic import BaseModel


class SharedModel(BaseModel):
    id: int | None = None
    name: str | None = None
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: model-reuse.reuse-scope-tree.output -->

---

## `--shared-module-name`

Customize the name of the shared module when using `--reuse-scope tree`.

```bash
datamodel-codegen --input schemas/ --output models/ \
  --reuse-model --reuse-scope tree --shared-module-name common
```

**Output:**
```text
models/
├── __init__.py
├── user.py
├── order.py
└── common.py      # Instead of shared.py
```

---

## `--collapse-root-models`

Inline root model definitions instead of creating separate wrapper classes.

### Without `--collapse-root-models`

```python
class UserId(BaseModel):
    __root__: str


class User(BaseModel):
    id: UserId
```

### With `--collapse-root-models`

```python
class User(BaseModel):
    id: str  # Inlined
```

### When to use

- Simpler output when wrapper classes aren't needed
- Reducing the number of generated classes
- When root models are just type aliases

---

## Combining Options

### Recommended for large multi-file projects

```bash
datamodel-codegen \
  --input schemas/ \
  --output models/ \
  --reuse-model \
  --reuse-scope tree \
  --shared-module-name common \
  --collapse-root-models
```

This produces:
- Deduplicated models across all files
- Shared types in a `common.py` module
- Inlined simple root models
- Minimal, clean output

### Recommended for single-file projects

```bash
datamodel-codegen \
  --input schema.json \
  --output model.py \
  --reuse-model \
  --collapse-root-models
```

---

## Performance Impact

For large schemas with many models:

| Scenario | Without reuse | With reuse |
|----------|---------------|------------|
| 100 schemas, 50% duplicates | 100 models | ~50 models |
| Generation time | Baseline | Faster (less to generate) |
| Output size | Large | Smaller |
| Git diff on type change | Multiple files | Single location |

!!! tip "Performance tip"
    For very large schemas, combine `--reuse-model` with `--disable-warnings` to speed up generation:

    ```bash
    datamodel-codegen --reuse-model --disable-warnings --input large-schema.json
    ```

---

## Output Structure Comparison

### Without deduplication

```text
models/
├── user.py         # UserStatus enum
├── order.py        # OrderStatus enum (duplicate of UserStatus!)
└── product.py      # ProductStatus enum (duplicate!)
```

### With `--reuse-model --reuse-scope tree`

```text
models/
├── __init__.py
├── user.py         # imports Status from shared
├── order.py        # imports Status from shared
├── product.py      # imports Status from shared
└── shared.py       # Status enum defined once
```

---

## Reducing Duplicate Field Types

When multiple classes share the same field type with identical constraints or metadata, you can reduce duplication by defining the type once in `$defs` and referencing it with `$ref`. Combined with `--use-type-alias`, this creates a single TypeAlias that's reused across all classes.

### Problem: Duplicate Annotated Fields

Without using `$ref`, each class gets its own inline field definition:

```python
class ClassA(BaseModel):
    place_name: Annotated[str, Field(alias="placeName")]  # Duplicate!


class ClassB(BaseModel):
    place_name: Annotated[str, Field(alias="placeName")]  # Duplicate!
```

### Solution: Use `$defs` with `--use-type-alias`

**Step 1: Define the shared type in `$defs`**

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: model-reuse.use-type-alias.schema -->
<!-- fmt: off -->

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Model",
  "$defs": {
    "PlaceName": {
      "type": "string",
      "title": "PlaceName",
      "description": "A place name with alias",
      "examples": ["Tokyo", "New York"]
    },
    "ClassA": {
      "type": "object",
      "title": "ClassA",
      "properties": {
        "place_name": {
          "$ref": "#/$defs/PlaceName"
        },
        "other_field": {
          "type": "integer"
        }
      },
      "required": ["place_name"]
    },
    "ClassB": {
      "type": "object",
      "title": "ClassB",
      "properties": {
        "place_name": {
          "$ref": "#/$defs/PlaceName"
        },
        "description": {
          "type": "string"
        }
      },
      "required": ["place_name"]
    }
  },
  "anyOf": [
    {"$ref": "#/$defs/ClassA"},
    {"$ref": "#/$defs/ClassB"}
  ]
}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: model-reuse.use-type-alias.schema -->

**Step 2: Generate with `--use-type-alias`**

```bash
datamodel-codegen \
  --input schema.json \
  --output model.py \
  --use-type-alias
```

### Result: Single TypeAlias reused across classes

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: model-reuse.use-type-alias.output -->
<!-- fmt: off -->

```python
from __future__ import annotations

from typing import Annotated

from pydantic import BaseModel, Field
from typing_extensions import TypeAliasType

PlaceName = TypeAliasType(
    "PlaceName",
    Annotated[
        str,
        Field(
            ...,
            description='A place name with alias',
            examples=['Tokyo', 'New York'],
            title='PlaceName',
        ),
    ],
)


class ClassA(BaseModel):
    place_name: PlaceName
    other_field: int | None = None


class ClassB(BaseModel):
    place_name: PlaceName
    description: str | None = None


Model = TypeAliasType("Model", Annotated[ClassA | ClassB, Field(..., title='Model')])
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: model-reuse.use-type-alias.output -->

### Benefits

- **Single source of truth** - Field type is defined once
- **Easier maintenance** - Change the type in one place
- **Cleaner generated code** - No redundant annotations
- **Type safety** - All fields share the exact same type

### When to Use This Pattern

This pattern is ideal when:

- Multiple classes share fields with the same constraints (e.g., `minLength`, `pattern`)
- Fields have identical metadata (e.g., `description`, `examples`)
- You want to ensure type consistency across your schema

---

## See Also

- [CLI Reference: `--reuse-model`](cli-reference/model-customization.md#reuse-model)
- [CLI Reference: `--reuse-scope`](cli-reference/model-customization.md#reuse-scope)
- [CLI Reference: `--collapse-root-models`](cli-reference/model-customization.md#collapse-root-models)
- [CLI Reference: `--use-type-alias`](cli-reference/typing-customization.md#use-type-alias)
- [Root Models and Type Aliases](root-model-and-type-alias.md)
- [FAQ: Performance](faq.md#performance)

---

# Module Structure and Exports

Source: https://datamodel-code-generator.koxudaxi.dev/module-exports/

<!-- related-cli-options: --all-exports-scope, --all-exports-collision-strategy, --treat-dot-as-module, --strict-dotted-module-names -->

# Module Structure and Exports

When generating models to a directory structure, datamodel-code-generator can automatically create `__init__.py` files with `__all__` exports. This page explains how to control this behavior.

## Quick Overview

| Option | Description |
|--------|-------------|
| `--all-exports-scope` | Control which modules get `__all__` exports |
| `--all-exports-collision-strategy` | Handle name collisions in recursive exports |
| `--treat-dot-as-module` | Convert dots in names to nested modules |
| `--strict-dotted-module-names` | Restrict automatic dotted-name inference to canonical Python identifiers |

---

## `--all-exports-scope`

Controls the scope of `__all__` generation in `__init__.py` files.

| Value | Description |
|-------|-------------|
| `none` | No `__all__` generation (default) |
| `local` | Export only the module's own definitions |
| `recursive` | Export all definitions from child modules |

### Example: `none` (default)

```bash
datamodel-codegen --input schemas/ --output models/
```

```python
# models/__init__.py
# (empty or minimal imports)
```

### Example: `local`

```bash
datamodel-codegen --input schemas/ --output models/ --all-exports-scope children
```

```python
# models/__init__.py
from .user import User
from .order import Order

__all__ = ["User", "Order"]
```

### Example: `recursive`

```bash
datamodel-codegen --input schemas/ --output models/ --all-exports-scope recursive
```

```python
# models/__init__.py
from .user import User
from .order import Order
from .common.status import Status
from .common.types import ID, Timestamp

__all__ = ["User", "Order", "Status", "ID", "Timestamp"]
```

---

## `--all-exports-collision-strategy`

When using `--all-exports-scope recursive`, name collisions can occur if multiple modules define the same class name. This option controls how to handle them.

| Value | Description |
|-------|-------------|
| `minimal-prefix` | Add minimum module path prefix to disambiguate |
| `full-prefix` | Use complete module path for all exports |

### The Problem

```text
models/
├── user/
│   └── types.py      # defines `ID`
└── order/
    └── types.py      # also defines `ID`
```

Both modules define `ID`, causing a collision when exporting recursively.

### Solution: `minimal-prefix`

```bash
datamodel-codegen --input schemas/ --output models/ \
  --all-exports-scope recursive \
  --all-exports-collision-strategy minimal-prefix
```

```python
# models/__init__.py
from .user.types import ID as user_ID
from .order.types import ID as order_ID

__all__ = ["user_ID", "order_ID"]
```

Only colliding names get prefixed.

### Solution: `full-prefix`

```bash
datamodel-codegen --input schemas/ --output models/ \
  --all-exports-scope recursive \
  --all-exports-collision-strategy full-prefix
```

```python
# models/__init__.py
from .user.types import ID as user_types_ID
from .order.types import ID as order_types_ID

__all__ = ["user_types_ID", "order_types_ID"]
```

All names use the full module path prefix.

---

## `--treat-dot-as-module`

Converts dots in schema names to nested module directories.

### Without `--treat-dot-as-module`

Schema with `title: "api.v1.User"` generates:

```python
# models.py
class ApiV1User(BaseModel): ...
```

### With `--treat-dot-as-module`

```bash
datamodel-codegen --input schema.json --output models/ --treat-dot-as-module
```

Schema with `title: "api.v1.User"` generates:

```text
models/
├── __init__.py
└── api/
    ├── __init__.py
    └── v1/
        ├── __init__.py
        └── user.py      # contains class User
```

This is useful for:

- Organizing large schemas by namespace
- Mirroring API versioning structure
- Keeping related models together

When writing plain Python text to stdout with the standard renderer and without
an explicit `--treat-dot-as-module` setting, historical automatic module
inference is preserved whenever the final concatenated result remains usable. A
retry coalesces the stdout models into one flat namespace only when a
non-canonical inferred module boundary leaves conflicting generated
definitions, repeats a future import after generated code, hides a generated
model with a later import, or emits a relative import that cannot resolve in
standalone stdout. Existing root and canonical model names are reserved first.
Directory output, JSON output, schema runtime validator or generic-base
generation, custom rendering, and the Python API retain their existing default
inference. Use directory or JSON output when module paths must be preserved.

## `--strict-dotted-module-names`

By default, automatic inference retains the historical behavior of treating dots
as module separators. Enable `--strict-dotted-module-names` to infer a module path
only when every raw segment, including the model name, is a canonical Python
identifier. Hard keywords, numeric or empty segments, punctuation, and names that
change under NFKC normalization fall back to a flat model name.

```bash
datamodel-codegen \
  --input schema.json \
  --output models.py \
  --strict-dotted-module-names
```

This option affects automatic inference only. Explicit
`--treat-dot-as-module` or `--no-treat-dot-as-module` takes precedence. The
negative form, `--no-strict-dotted-module-names`, can disable a value enabled in
`pyproject.toml`; it does not disable the narrow unusable-stdout repair described
above. Use explicit `--treat-dot-as-module` when module boundaries must be kept.

---

## Common Patterns

### Pattern 1: Flat directory output with child exports

Best for small to medium projects with a single generated package or simple directory structure.

```bash
datamodel-codegen --input schema.yaml --output models/ --all-exports-scope children
```

### Pattern 2: Hierarchical with recursive exports

Best for large projects with many schemas organized by domain.

```bash
datamodel-codegen --input schemas/ --output models/ \
  --all-exports-scope recursive \
  --all-exports-collision-strategy minimal-prefix \
  --treat-dot-as-module
```

### Pattern 3: OpenAPI with module structure

Best for OpenAPI schemas with versioned endpoints.

```bash
datamodel-codegen --input openapi.yaml --output models/ \
  --treat-dot-as-module \
  --all-exports-scope recursive
```

---

## Troubleshooting

### Import errors after generation

If you see `ImportError: cannot import name 'X'`:

1. Check if `__all__` is generated correctly
2. Verify the module structure matches your imports
3. Try `--all-exports-scope children` first, then `recursive`

### Name collisions

If you see duplicate class names:

1. Use `--all-exports-collision-strategy minimal-prefix`
2. Or use `--all-exports-collision-strategy full-prefix` for maximum clarity
3. Consider restructuring your schemas to avoid collisions

### Circular imports

If you encounter circular import errors:

1. Check the generated `__init__.py` files
2. Consider using `--all-exports-scope children` instead of `recursive`
3. Use lazy imports in your application code

---

## See Also

- [CLI Reference: `--all-exports-scope`](cli-reference/general-options.md#all-exports-scope)
- [CLI Reference: `--all-exports-collision-strategy`](cli-reference/general-options.md#all-exports-collision-strategy)
- [CLI Reference: `--treat-dot-as-module`](cli-reference/template-customization.md#treat-dot-as-module)
- [CLI Reference: `--strict-dotted-module-names`](cli-reference/template-customization.md#strict-dotted-module-names)
- [Model Reuse and Deduplication](model-reuse.md)

---

# Type Mappings and Custom Types

Source: https://datamodel-code-generator.koxudaxi.dev/type-mappings/

<!-- related-cli-options: --type-mappings, --strict-types, --output-datetime-class, --use-pendulum, --use-decimal-for-multiple-of -->

# Type Mappings and Custom Types

datamodel-code-generator allows you to customize how schema types are mapped to Python types. This is essential for projects with specific type requirements, datetime handling preferences, or third-party library integrations.

## Quick Overview

| Option | Description |
|--------|-------------|
| `--type-mappings` | Map schema types to custom Python types |
| `--strict-types` | Use Pydantic strict types for validation |
| `--output-datetime-class` | Choose datetime output type |
| `--use-pendulum` | Use Pendulum library for datetime types |
| `--use-decimal-for-multiple-of` | Use Decimal for multipleOf constraints |
| `format: "email"` | Email validation (requires `email-validator`) |
| `format: "ulid"` | ULID type support (requires `python-ulid`) |

---

## `--type-mappings`

Maps schema type+format combinations to other format names. This allows you to override how specific formats are interpreted.

### Format

```bash
--type-mappings <type+format>=<target_format> [<type+format>=<target_format> ...]
```

### Basic Examples

```bash
# Map binary format to string (generates str instead of bytes)
datamodel-codegen --input schema.json --output models.py \
  --type-mappings "binary=string"

# Map email format to string (generates str instead of EmailStr)
datamodel-codegen --input schema.json --output models.py \
  --type-mappings "string+email=string"

# Multiple mappings
datamodel-codegen --input schema.json --output models.py \
  --type-mappings "string+email=string" "string+uuid=string"
```

### Mapping Syntax

| Syntax | Description | Example |
|--------|-------------|---------|
| `format=target` | Map format (assumes string type) | `binary=string` |
| `type+format=target` | Map type with format | `string+email=string` |

### Avoiding Pydantic Optional Extras

Some Pydantic types require optional dependencies. Use `--type-mappings` to generate plain types instead:

```bash
# Avoid pydantic[email] dependency (EmailStr requires email-validator)
--type-mappings "string+email=string" "string+idn-email=string"

# Generate str instead of UUID for uuid format
--type-mappings "string+uuid=string"
```

### Available Target Formats

| Target | Generated Type |
|--------|----------------|
| `string` | `str` |
| `integer` | `int` |
| `number` | `float` |
| `boolean` | `bool` |
| `binary` | `bytes` |
| `date` | `datetime.date` |
| `date-time` | `datetime.datetime` |
| `uuid` | `UUID` |
| `email` | `EmailStr` |
| `uri` | `AnyUrl` |

### pyproject.toml Configuration

```toml
[tool.datamodel-codegen]
type-mappings = [
    "string+email=string",
    "string+idn-email=string",
    "binary=string",
]
```

---

## `--strict-types`

Generates Pydantic strict types that don't perform type coercion during validation.

### Available Strict Types

| Value | Strict Type | Rejects |
|-------|-------------|---------|
| `str` | `StrictStr` | Integers, floats |
| `int` | `StrictInt` | Strings, floats |
| `float` | `StrictFloat` | Strings, integers |
| `bool` | `StrictBool` | Strings, integers |
| `bytes` | `StrictBytes` | Strings |

### Without `--strict-types`

```python
class User(BaseModel):
    id: int  # Accepts "123" and converts to 123
    name: str  # Accepts 123 and converts to "123"
    active: bool  # Accepts 1 and converts to True
```

### With `--strict-types`

```bash
datamodel-codegen --input schema.json --output models.py \
  --strict-types str int bool
```

```python
from pydantic import StrictBool, StrictInt, StrictStr


class User(BaseModel):
    id: StrictInt  # Rejects "123", requires integer
    name: StrictStr  # Rejects 123, requires string
    active: StrictBool  # Rejects 1, requires boolean
```

### When to use

- API validation where type coercion is undesirable
- Data pipelines requiring exact types
- Security-sensitive applications
- Testing environments requiring strict type checking

---

## `--output-datetime-class`

Controls the Python type used for `date-time` formatted strings.

| Value | Output Type | Description |
|-------|-------------|-------------|
| `datetime` | `datetime.datetime` | Standard library datetime (default) |
| `AwareDatetime` | `pydantic.AwareDatetime` | Requires timezone info |
| `NaiveDatetime` | `pydantic.NaiveDatetime` | Rejects timezone info |

### Default behavior

```python
from datetime import datetime


class Event(BaseModel):
    created_at: datetime  # Accepts both aware and naive
```

### AwareDatetime (recommended for APIs)

```bash
datamodel-codegen --input schema.json --output models.py \
  --output-datetime-class AwareDatetime
```

```python
from pydantic import AwareDatetime


class Event(BaseModel):
    created_at: AwareDatetime  # Requires timezone, e.g., 2024-01-01T00:00:00Z
```

### NaiveDatetime

```bash
datamodel-codegen --input schema.json --output models.py \
  --output-datetime-class NaiveDatetime
```

```python
from pydantic import NaiveDatetime


class Event(BaseModel):
    created_at: NaiveDatetime  # Rejects timezone, e.g., 2024-01-01T00:00:00
```

### When to use each

| Use Case | Recommended Class |
|----------|-------------------|
| REST APIs | `AwareDatetime` |
| Database models | `datetime` or `NaiveDatetime` |
| Logs with UTC timestamps | `AwareDatetime` |
| Local time applications | `NaiveDatetime` |

---

## `--use-pendulum`

Uses [Pendulum](https://pendulum.eustace.io/) library types instead of standard library datetime.

```bash
pip install pendulum
datamodel-codegen --input schema.json --output models.py --use-pendulum
```

### Output

```python
import pendulum


class Event(BaseModel):
    created_at: pendulum.DateTime
    date: pendulum.Date
    time: pendulum.Time
```

### Benefits of Pendulum

- Timezone handling is simpler and more intuitive
- Human-friendly datetime manipulation
- Better serialization defaults
- Immutable by default

### When to use

- Projects already using Pendulum
- Applications requiring complex datetime manipulation
- When timezone handling is a priority

---

## Email Format Support

The generator supports the `email` and `idn-email` string formats, which generate Pydantic's `EmailStr` type.

!!! warning "Required Dependency"
    The `email` format requires the `email-validator` package to be installed:
    ```bash
    pip install email-validator
    ```
    Or install Pydantic with the email extra:
    ```bash
    pip install pydantic[email]
    ```

### Schema Example

```json
{
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "format": "email"
    }
  }
}
```

### Output

```python
from pydantic import BaseModel, EmailStr


class MyModel(BaseModel):
    email: EmailStr
```

### Avoiding the Dependency

If you don't want to install `email-validator`, you can map email formats to plain strings:

```bash
datamodel-codegen --input schema.json --output models.py \
  --type-mappings "string+email=string" "string+idn-email=string"
```

This generates `str` instead of `EmailStr`.

---

## ULID Format Support

The generator supports the `ulid` string format, which generates [`python-ulid`](https://github.com/mdomke/python-ulid) types.

!!! warning "Required Dependency"
    The `ulid` format requires the `python-ulid` package to be installed:
    ```bash
    pip install python-ulid
    ```
    For Pydantic integration, use:
    ```bash
    pip install python-ulid[pydantic]
    ```

### Schema Example

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "ulid"
    }
  }
}
```

### Output

```python
from ulid import ULID
from pydantic import BaseModel


class MyModel(BaseModel):
    id: ULID
```

### What is ULID?

ULID (Universally Unique Lexicographically Sortable Identifier) is an alternative to UUID that offers:

- **Lexicographic sorting** - ULIDs sort naturally by creation time
- **Compactness** - 26 characters vs 36 for UUID
- **URL-safe** - Uses Crockford's Base32 encoding
- **Timestamp encoded** - First 10 characters encode creation time

### When to use

- Distributed systems requiring time-ordered IDs
- Applications where database index performance matters
- When you need both uniqueness and sortability

---

## `--use-decimal-for-multiple-of`

Uses `Decimal` type for numbers with `multipleOf` constraints to avoid floating-point precision issues.

### The Problem

```yaml
properties:
  price:
    type: number
    multipleOf: 0.01  # Currency precision
```

Without this option, floating-point arithmetic can cause validation issues:

```python
# 0.1 + 0.2 = 0.30000000000000004 in floating-point
price = 0.30000000000000004  # May fail multipleOf validation
```

### Solution

```bash
datamodel-codegen --input schema.json --output models.py \
  --use-decimal-for-multiple-of
```

```python
from decimal import Decimal


class Product(BaseModel):
    price: Decimal  # Exact decimal arithmetic
```

### When to use

- Financial applications
- Scientific calculations requiring precision
- Any schema with `multipleOf` constraints

---

## Common Patterns

### Pattern 1: Minimal dependencies

Avoid optional Pydantic dependencies by mapping special formats to plain types:

```bash
datamodel-codegen --input schema.json --output models.py \
  --type-mappings "string+email=string" "string+idn-email=string"
```

### Pattern 2: Strict API validation

```bash
datamodel-codegen --input schema.json --output models.py \
  --strict-types str int float bool \
  --output-datetime-class AwareDatetime \
  --field-constraints
```

### Pattern 3: Financial application

```bash
datamodel-codegen --input schema.json --output models.py \
  --use-decimal-for-multiple-of \
  --strict-types str int
```

### Pattern 4: Pendulum datetime handling

```bash
datamodel-codegen --input schema.json --output models.py \
  --use-pendulum \
  --strict-types str int
```

---

## Type Mapping Reference

### Common Format Mappings

| Schema Format | Default Type | With `--type-mappings "format=string"` |
|---------------|--------------|----------------------------------------|
| `email` | `EmailStr` | `str` |
| `idn-email` | `EmailStr` | `str` |
| `uuid` | `UUID` | `str` |
| `ulid` | `ULID` (requires `python-ulid`) | `str` |
| `uri` | `AnyUrl` | `str` |
| `binary` | `bytes` | `str` |

!!! note "Other type customization options"
    For datetime types, use `--output-datetime-class` or `--use-pendulum` instead of `--type-mappings`.

---

## See Also

- [CLI Reference: `--type-mappings`](cli-reference/typing-customization.md#type-mappings)
- [CLI Reference: `--strict-types`](cli-reference/typing-customization.md#strict-types)
- [CLI Reference: `--output-datetime-class`](cli-reference/typing-customization.md#output-datetime-class)
- [CLI Reference: `--use-pendulum`](cli-reference/typing-customization.md#use-pendulum)
- [Field Constraints](field-constraints.md)
- [Python Version Compatibility](python-version-compatibility.md)

---

# Python Version Compatibility

Source: https://datamodel-code-generator.koxudaxi.dev/python-version-compatibility/

<!-- related-cli-options: --target-python-version, --use-union-operator, --use-standard-collections, --use-annotated, --disable-future-imports, --use-generic-container-types -->

# Python Version Compatibility

datamodel-code-generator can generate code compatible with different Python versions. This page explains how to control type annotation syntax and imports for your target environment.

## Quick Overview

| Option | Description |
|--------|-------------|
| `--target-python-version` | Set the minimum Python version for generated code |
| `--use-union-operator` | Use `X \| Y` instead of `Union[X, Y]` |
| `--use-standard-collections` | Use `list`, `dict` instead of `List`, `Dict` |
| `--use-annotated` | Use `Annotated` for field metadata |
| `--use-generic-container-types` | Use `Sequence`, `Mapping` instead of `list`, `dict` |
| `--disable-future-imports` | Don't add `from __future__ import annotations` |

---

## `--target-python-version`

Sets the minimum Python version for the generated code. This automatically adjusts type annotation syntax.

| Version | Union Syntax | Collection Syntax | Notes |
|---------|--------------|-------------------|-------|
| 3.10 | `X \| Y` | `list[T]`, `dict[K, V]` | Union operator available |
| 3.11 | `X \| Y` | `list[T]`, `dict[K, V]` | `Self` type available |
| 3.12 | `X \| Y` | `list[T]`, `dict[K, V]` | `type` statement available |
| 3.13 | `X \| Y` | `list[T]`, `dict[K, V]` | `ReadOnly` TypedDict keys imported from `typing` |
| 3.14 | `X \| Y` | `list[T]`, `dict[K, V]` | Native deferred annotations: `from __future__ import annotations` only where the output model needs it for forward references |
| 3.15 | `X \| Y` | `list[T]`, `dict[K, V]` | `TypedDict` with `closed`/`extra_items` (PEP 728) imported from `typing`; `frozendict` builtin |

### Example: Python 3.10+

```bash
datamodel-codegen --input schema.json --output models.py \
  --target-python-version 3.10
```

```python
class User(BaseModel):
    id: int
    tags: list[str]
    metadata: str | int | None = None
```

---

## `--use-union-operator`

Uses the `|` operator for union types instead of `Union[X, Y]`.

### Without `--use-union-operator`

```python
from typing import Union, Optional


class Item(BaseModel):
    value: Union[str, int]
    label: Optional[str] = None  # Same as Union[str, None]
```

### With `--use-union-operator`

```bash
datamodel-codegen --input schema.json --output models.py --use-union-operator
```

```python
class Item(BaseModel):
    value: str | int
    label: str | None = None
```

### Compatibility Note

The union operator `|` requires:
- Python 3.10+ at runtime, OR
- `from __future__ import annotations` (Python 3.7+) for postponed evaluation

---

## `--use-standard-collections`

Uses built-in collection types instead of `typing` module generics.

### Without `--use-standard-collections`

```python
from typing import List, Dict, Set, Tuple


class Data(BaseModel):
    items: List[str]
    mapping: Dict[str, int]
    unique: Set[str]
    pair: Tuple[str, int]
```

### With `--use-standard-collections`

```bash
datamodel-codegen --input schema.json --output models.py --use-standard-collections
```

```python
class Data(BaseModel):
    items: list[str]
    mapping: dict[str, int]
    unique: set[str]
    pair: tuple[str, int]
```

### Compatibility Note

Built-in generic syntax requires:
- Python 3.10+ at runtime, OR
- `from __future__ import annotations`

---

## `--use-annotated`

Uses `typing.Annotated` to attach metadata to types, which is the modern approach for Pydantic v2.

### Without `--use-annotated`

```python
from pydantic import Field


class User(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    age: int = Field(..., ge=0, le=150)
```

### With `--use-annotated`

```bash
datamodel-codegen --input schema.json --output models.py --use-annotated
```

```python
from typing import Annotated
from pydantic import Field


class User(BaseModel):
    name: Annotated[str, Field(min_length=1, max_length=100)]
    age: Annotated[int, Field(ge=0, le=150)]
```

### Benefits

- Cleaner separation of type and constraints
- Better IDE support
- More compatible with other tools that understand `Annotated`
- Required types are more explicit

---

## `--use-generic-container-types`

Uses abstract container types (`Sequence`, `Mapping`, `FrozenSet`) instead of concrete types (`list`, `dict`, `set`).

```bash
datamodel-codegen --input schema.json --output models.py --use-generic-container-types
```

```python
from typing import Mapping, Sequence


class Data(BaseModel):
    items: Sequence[str]
    mapping: Mapping[str, int]
```

If `--use-standard-collections` is also set, imports from `collections.abc` instead of `typing`.

This is useful when:
- You want to use abstract types for better type flexibility
- Maintaining compatibility with interfaces that accept any sequence/mapping

---

## `--disable-future-imports`

Prevents adding `from __future__ import annotations` to generated files.

### Default behavior (with future imports)

```python
from __future__ import annotations


class User(BaseModel):
    friends: list[User]  # Forward reference works due to PEP 563
```

### With `--disable-future-imports`

```bash
datamodel-codegen --input schema.json --output models.py --disable-future-imports
```

```python
from typing import List, TYPE_CHECKING

if TYPE_CHECKING:
    from typing import ForwardRef


class User(BaseModel):
    friends: List["User"]  # String forward reference
```

### When to disable

- Compatibility with runtime annotation inspection
- Libraries that don't support `__future__.annotations`
- When using `get_type_hints()` at runtime

---

## Common Patterns

### Pattern 1: Modern Python (3.10+)

For projects targeting Python 3.10 or later:

```bash
datamodel-codegen --input schema.json --output models.py \
  --target-python-version 3.10 \
  --use-union-operator \
  --use-standard-collections \
  --use-annotated
```

Output:
```python
from typing import Annotated
from pydantic import BaseModel, Field


class User(BaseModel):
    id: int
    name: Annotated[str, Field(min_length=1)]
    tags: list[str]
    metadata: dict[str, str] | None = None
```

### Pattern 2: Minimum Supported Python (3.10)

For projects targeting Python 3.10 (minimum supported version):

```bash
datamodel-codegen --input schema.json --output models.py \
  --target-python-version 3.10
```

Output:
```python
class User(BaseModel):
    id: int
    name: str
    tags: list[str]
    metadata: dict[str, str] | None = None
```

### Pattern 3: Maximum compatibility

For libraries that need to work across multiple Python versions (3.10+):

```bash
datamodel-codegen --input schema.json --output models.py \
  --target-python-version 3.10
```

The generator will use modern Python 3.10+ syntax including union operators and built-in generic types.

### Pattern 4: CI/CD consistency

Pin the Python version in `pyproject.toml` to ensure consistent output:

```toml
[tool.datamodel-codegen]
target-python-version = "3.10"
use-union-operator = true
use-standard-collections = true
use-annotated = true
```

---

## Version Feature Matrix

| Feature | 3.10 | 3.11 | 3.12 | 3.13 | 3.14 | 3.15 |
|---------|------|------|------|------|------|------|
| `list[T]` syntax | native | native | native | native | native | native |
| `X \| Y` union | native | native | native | native | native | native |
| `Annotated` | native | native | native | native | native | native |
| `TypeAlias` | native | native | native | native | native | native |
| `Self` | `typing_extensions` | native | native | native | native | native |
| `type` statement | N/A | N/A | native | native | native | native |
| TypedDict `NotRequired` | `typing_extensions` | native | native | native | native | native |
| TypedDict `ReadOnly` | `typing_extensions` | `typing_extensions` | `typing_extensions` | native | native | native |
| TypedDict `closed`/`extra_items` (PEP 728) | `typing_extensions` | `typing_extensions` | `typing_extensions` | `typing_extensions` | `typing_extensions` | native |
| Deferred annotations | `__future__` import | `__future__` import | `__future__` import | `__future__` import | native (`__future__` import where needed) | native (`__future__` import where needed) |
| `frozendict` in `x-python-type` | N/A | N/A | N/A | N/A | N/A | native |
| `TypeForm`, `NoExtraItems`, `disjoint_base` in `x-python-type` | `typing_extensions` | `typing_extensions` | `typing_extensions` | `typing_extensions` | `typing_extensions` | native |

A standard-library type named by `--type-overrides`, `customTypePath` or `x-python-import` follows the same rules as
`x-python-type`: a `typing` or `collections.abc` name newer than the target is imported from `typing_extensions`, and
a type that the target does not have, such as `enum.StrEnum` for 3.10 or `pathlib.DirEntryInfo` for 3.15, stops the
generation with `<type> is unavailable for target Python <version>`. These types are checked only where the output
imports them, after `--import-overrides`, so an override that no model uses, or a `customTypePath` that an override
replaces, is left alone, and `--import-overrides` can move such an import to a backport module, as
`--import-overrides '{"StrEnum": "backports.strenum"}'` does for `enum.StrEnum` on 3.10.

---

## Troubleshooting

### TypeError: 'type' object is not subscriptable

This occurs when using `list[T]` syntax on older Python versions without `__future__` imports.

**Solution:** Ensure you are running Python 3.10+ or use `from __future__ import annotations`.

### Pydantic validation fails with forward references

This can happen when `__future__.annotations` interacts poorly with Pydantic's type resolution.

**Solution:** Try `--disable-future-imports` or update to Pydantic v2.

### Python 3.13 DeprecationWarning with `typing._eval_type`

When running on Python 3.13+ with `from __future__ import annotations`, you may see:

```text
DeprecationWarning: Failing to pass a value to the 'type_params' parameter
of 'typing._eval_type' is deprecated...
```

This occurs because Python 3.13 deprecated calling `typing._eval_type()` without the `type_params` parameter. Libraries that evaluate forward references (like older Pydantic versions) trigger this warning.

**Solutions:**

1. **Upgrade Pydantic** (recommended):
   - Pydantic v2: Upgrade to the latest version

2. **Use `--disable-future-imports`** as a workaround:
   ```bash
   datamodel-codegen --input schema.json --output models.py --disable-future-imports
   ```

3. **Suppress the warning** in pytest (temporary fix):
   ```toml
   # pyproject.toml
   [tool.pytest.ini_options]
   filterwarnings = [
       "ignore::DeprecationWarning:pydantic.typing",
   ]
   ```

!!! note
    Targets of Python 3.14 or later use native deferred annotations (PEP 649). The generator still
    adds `from __future__ import annotations` when the output model needs explicit deferred
    annotations for forward references or types hidden by same-named fields.

### IDE shows type errors

Some IDEs don't fully understand `from __future__ import annotations`.

**Solution:** Configure your IDE's Python version or use explicit type syntax matching your runtime version.

---

## See Also

- [CLI Reference: `--target-python-version`](cli-reference/model-customization.md#target-python-version)
- [CLI Reference: `--use-union-operator`](cli-reference/typing-customization.md#use-union-operator)
- [CLI Reference: `--use-standard-collections`](cli-reference/typing-customization.md#use-standard-collections)
- [CLI Reference: `--use-annotated`](cli-reference/typing-customization.md#use-annotated)
- [Output Model Types](output-model-types.md)
- [Type Mappings and Custom Types](type-mappings.md)
- [CI/CD Integration](ci-cd.md)

---

# Root Models and Type Aliases

Source: https://datamodel-code-generator.koxudaxi.dev/root-model-and-type-alias/

<!-- related-cli-options: --use-type-alias, --use-type-alias-type, --target-python-version -->

# 📦 Root Models and Type Aliases

When a schema defines a simple type (not an object with properties), `datamodel-code-generator` creates a root model. If you don't want to introduce a new level of attribute access (`.root`) or want to use generated types as plain Python types in non-Pydantic code, you can use the `--use-type-alias` flag to generate type aliases instead of root models.

## ⚠️ Notes and Limitations

**This functionality is experimental!** Here are a few known issues:

- 📌 RootModel and type aliases do not fully support field-specific metadata (default, alias, etc). See [Named Type Aliases](https://docs.pydantic.dev/latest/concepts/types/#named-type-aliases) for details.
- 🚫 Type aliases do not support some RootModel features (e.g. `model_config`)
- 📄 A RootModel or type alias is also generated for the main schema, allowing you to define a single type alias from a schema file (e.g. `model.json` containing `{"title": "MyString", "type": "string"}`)
- 🧩 Pydantic v2 type aliases express constraints as `Annotated[int, Field(ge=1)]` instead of `conint(ge=1)`, because mypy and Pyright reject call expressions in type aliases. A `Decimal` `multipleOf` uses `annotated_types.MultipleOf`, because `Field` types `multiple_of` as a float. Validation, serialization, and JSON schema stay the same, except that on Pydantic 2.0.x a string alias with `minLength: 0` now keeps `minLength: 0` in its JSON schema.
- 🔤 Pydantic v2 type aliases (`--use-type-alias` and `pydantic_v2.dataclass` output) cannot select Python's regex engine through `model_config`, so patterns that need it, such as lookaround assertions, are generated as compiled `re.compile(...)` patterns. These aliases require **Pydantic 2.8 or later in the environment that runs the generated code**, because [Pydantic 2.8 added support for compiled patterns](https://pydantic.dev/articles/pydantic-v2-8-release#respect-regex-flags-in-constrained-string-validation). With `--target-pydantic-version 2` these patterns stay strings and every generated model that reaches the alias, directly or through other models, sets `regex_engine="python-re"`, which works from Pydantic 2.5; hand-written models that embed generated ones must set it themselves, and an alias validated on its own then needs `TypeAdapter(Alias, config=ConfigDict(regex_engine="python-re"))`. See [Targeting a Pydantic version](output-model-types.md#targeting-a-pydantic-version).

When `--use-root-model-type-alias` is enabled, roots with field constraints or
patterns that require Python regex configuration use a regular `RootModel` class
to preserve validation. Unconstrained roots and constraints already represented
in the alias type keep the alias form. This does not change `--use-type-alias`.
An existing custom `pydantic_v2/RootModelTypeAlias.jinja2` remains selected;
that template is responsible for preserving its root constraints.

## API scope parameters

!!! note "Changed in 0.84.0"
    With `--openapi-scopes api`, OpenAPI path, query, header, and cookie parameter schemas that would be root models
    are always generated as type aliases, exactly as `--use-type-alias` emits them, whatever the output model type
    and options; 0.83.0 generated root models for them. Object parameters stay models, and component schemas keep
    their usual root models. See
    [OpenAPI Options: Generate all API declarations](openapi-options.md#generate-all-api-declarations).

## API scope references

!!! note "Changed in 0.84.0"
    With `--openapi-scopes api`, a `$ref` beside only annotations such as `description`, `title`, `examples`, or
    `x-` extensions is the referenced model itself, so a parameter, body, or response that refers to a `RootModel`
    component is that `RootModel` rather than a second one wrapping it. Siblings that change the values, or
    `nullable: true`, still give a derived model. See
    [OpenAPI Options: Generate all API declarations](openapi-options.md#generate-all-api-declarations).

## 📊 Type Alias Behavior by Output Type and Python Version

The type of type alias generated depends on the output model type and target Python version:

| Output Type | Python 3.12+ | Python 3.10-3.11 |
|-------------|--------------|------------------|
| **Pydantic v2** | `type` statement | `TypeAliasType` (typing_extensions) |
| **TypedDict** | `type` statement | `TypeAlias` |
| **dataclasses** | `type` statement | `TypeAlias` |
| **msgspec** | `type` statement | `TypeAlias` |

Use `--use-type-alias-type` to force `TypeAliasType` for TypedDict,
dataclass, and msgspec output targeting Python 3.10 or 3.11. This option
implies `--use-type-alias`, so the two flags do not need to be combined.
Python 3.12 and newer still use the native `type` statement.

### 🤔 Why the difference?

- **Pydantic v2** requires `TypeAliasType` because it cannot properly handle `TypeAlias` annotations
- **Other output types** (TypedDict, dataclasses, msgspec) use `TypeAlias` for better compatibility with libraries that may not expect `TypeAliasType` objects
- **`--use-type-alias-type`** opts into runtime `TypeAliasType` objects for those output types on Python 3.10-3.11
- **Python 3.12+** uses the native `type` statement for all output types

## 📝 Example

### model.json

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "UserId": {
      "type": "string"
    },
    "Status": {
      "anyOf": [
        {"type": "string"},
        {"type": "integer"}
      ]
    },
    "User": {
      "type": "object",
      "properties": {
        "id": {"$ref": "#/definitions/UserId"},
        "status": {"$ref": "#/definitions/Status"}
      }
    }
  }
}
```

### 🔸 Pydantic v2

#### Generating RootModel

```bash
datamodel-codegen --input model.json --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel --output model.py
```

### ✨ Generated model.py (Pydantic v2)

```python
# generated by datamodel-codegen:
#   filename:  model.json

from __future__ import annotations

from typing import Any, Optional, Union

from pydantic import BaseModel, RootModel


class Model(RootModel[Any]):
    root: Any


class UserId(RootModel[str]):
    root: str


class Status(RootModel[Union[str, int]]):
    root: Union[str, int]


class User(BaseModel):
    id: Optional[UserId] = None
    status: Optional[Status] = None
```

#### Generating type statement (Python 3.12+)

```bash
datamodel-codegen --input model.json --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel --use-type-alias --target-python-version 3.12 --output model.py
```

### ✨ Generated model.py (Python 3.12+ type statement)

```python
# generated by datamodel-codegen:
#   filename:  model.json

from __future__ import annotations

from typing import Any, Optional, Union

from pydantic import BaseModel

type Model = Any


type UserId = str


type Status = Union[str, int]


class User(BaseModel):
    id: Optional[UserId] = None
    status: Optional[Status] = None
```

---

## 📖 See Also

- 🖥️ [CLI Reference: `--use-type-alias`](cli-reference/typing-customization.md#use-type-alias) - Detailed CLI option documentation
- 🖥️ [CLI Reference: `--use-type-alias-type`](cli-reference/typing-customization.md#use-type-alias-type) - Force runtime type alias objects before Python 3.12
- 🎯 [CLI Reference: `--target-python-version`](cli-reference/model-customization.md#target-python-version) - Control Python version-specific syntax

---

# Field Constraints

Source: https://datamodel-code-generator.koxudaxi.dev/field-constraints/

<!-- related-cli-options: --field-constraints -->

# 🔒 Field Constraints

The `--field-constraints` option converts all `con*` annotations (like `conint`, `constr`) to `Field` constraint options.

## 🤔 Why use this?

Mypy may show errors for `con*` annotations on fields. The `--field-constraints` option resolves this problem by using standard `Field()` constraints instead.

## 📝 Example

Convert simple JSON Schema `model.json` to pydantic model `model.py`:

**model.json**
```json
{
  "type":  "object",
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 64
    }
  },
  "required": ["name"]
}
```

### ❌ Without `--field-constraints` option

```bash
datamodel-codegen --input model.json --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel > model.py
```

**Generated model.py**
```python
# generated by datamodel-codegen:
#   filename:  model.json
#   timestamp: 2020-07-20T15:37:56+00:00

from __future__ import annotations

from pydantic import BaseModel, constr


class Model(BaseModel):
    name: constr(max_length=64)
```

**🔴 Run mypy...**
```bash
$ mypy model.py
model.py:3: error: Invalid type comment or annotation
model.py:3: note: Suggestion: use constr[...] instead of constr(...)
Found 1 error in 1 file (checked 1 source file)
```

mypy shows errors! 😱

---

### ✅ With `--field-constraints` option

```bash
datamodel-codegen \
  --input model.json \
  --input-file-type jsonschema \
  --output-model-type pydantic_v2.BaseModel \
  --use-annotated \
  --field-constraints \
  > model.py
```

**Generated model.py**
```python
# generated by datamodel-codegen:
#   filename:  model.json
#   timestamp: 2020-07-20T15:47:21+00:00

from __future__ import annotations

from typing import Annotated

from pydantic import BaseModel, Field


class Model(BaseModel):
    name: Annotated[str, Field(max_length=64)]
```

**🟢 Run mypy...**
```bash
$ mypy model.py
Success: no issues found in 1 source file
```

No errors! 🎉

---

## 🔢 Which fields keep number keywords

`minimum`, `maximum`, `exclusiveMinimum`, `exclusiveMaximum` and `multipleOf` are written on a field in two cases.

**The schema holds a number.** The schema type is `number` or `integer`, or the type and format map to a number type
(`string` with `decimal`, `integer` or `unixtime`, or a format that `--type-mappings` maps to one). All five keywords
are written, as `con*` types by default and as `Field()` arguments with `--field-constraints` or `--use-annotated`.

**The Python type written for the field takes the keyword**, whatever the schema type is: a string format such as
`duration`, `date-time` or `time`, `x-python-type`, `customTypePath`, `--type-overrides`. A schema without `type` is
written as `Any`, which takes no number keyword. Pydantic models and dataclasses write these keywords only as `Field()`
arguments, so this case needs `--field-constraints` or `--use-annotated` (root models and type aliases follow the same
options); without them such a field has no bound. `msgspec.Struct` writes them as `Meta(...)`.

In both cases `msgspec.Struct` writes a keyword only when msgspec accepts it on the Python type, as the msgspec column
of the tables below lists, because msgspec cannot decode a model whose `Meta(...)` holds any other. A keyword it
leaves out, such as `minimum` on the `Decimal` of format `decimal`, is named with its field in a warning.
msgspec checks `multipleOf` on a `float` by its floating-point remainder, so `msgspec.Struct` writes it on a `float`
only for a divisor a float represents exactly, such as `2`, `0.5` or `1.5`; a divisor such as `0.01`, whose multiples
msgspec would reject, is left out with the same warning.
msgspec checks all members of a union that it decodes as one Python type against the constraints of each of them, so
in `anyOf: [{type: string, format: binary}, {type: string, format: binary, maxLength: 3}]` the `maxLength` of one
branch would reject the bytes the other branch accepts. `msgspec.Struct` writes such members without `Meta(...)`, so
the field takes the values of every branch (`bytes` here), and names the keywords it leaves out in the same warning;
members of different types, such as `str` and `int`, keep their constraints. msgspec counts the members of an alias of
a union, or of a type and `null`, as members of the union that names it, so a branch that references such a schema is
written as the alias's members there, while the alias keeps its `Meta(...)`. msgspec also decodes every integer as the
`int` member of a union that has a `float` member, so in
`anyOf: [{type: integer, maximum: 3}, {type: number, minimum: 5}]` the `maximum` would reject `6`, which the number
branch accepts; the `int` member is written without its constraints, with the same warning, unless they admit every
integer the `float` members admit.

| Python type | Pydantic | msgspec |
|-------------|----------|---------|
| `int`, `float` | all five keywords | all five keywords |
| `Decimal` | all five keywords | none |
| `timedelta` | the four bounds, read as seconds | none |
| `datetime`, `AwareDatetime`, `NaiveDatetime`, `PastDatetime`, `FutureDatetime` | the four bounds, read as seconds since the Unix epoch | none |
| `time` | the four bounds, read as seconds since midnight | none |
| a type the generator does not know (`fractions.Fraction`, a class of your own) or a model that the schema references | all five keywords | all five keywords |
| any other known type: `str`, `bytes`, `bool`, `None`, `date`, `UUID`, `Any`, `object`, paths, IP addresses, lists, dicts and other containers | none | none |

`multipleOf` is not written on `timedelta`, `datetime` and `time`: Pydantic 2.0 to 2.10 cannot build such a field,
and later versions ignore the keyword or fail on valid values. A `date` takes no number keyword in any Pydantic
version. `msgspec` accepts number constraints on `int` and `float` only, so a type the generator does not know has to
be one of them at runtime, for example a `NewType` of `int`.
Pydantic 2.11 cannot build a `time` field that has a number bound; use Pydantic 2.12 or later for such schemas.

A known type is a Python builtin or a standard-library type that the `--target-python-version` has, or a type the
generator itself imports; its row above decides. A name the target does not have yet, such as `frozendict` for a
target below 3.15, is read as a type the generator does not know. A `typing` alias or an abstract collection is read as the class it stands for (`typing.List`,
`collections.abc.Sequence` and `collections.abc.Collection` as `list`), and `Annotated[T, ...]` or `Final[T]` as `T`;
a `typing_extensions` name that `typing` also exports is read as the `typing` name. Any other `typing` or
`collections.abc` name, such as `typing.SupportsInt` or `collections.abc.Callable`, is a known type that takes no
number keyword. A union keeps a keyword only when every member other than `None` takes it, so `int | None` keeps the
keywords in Pydantic models and `int | str` does not; `msgspec` writes no type-dependent keyword (number, string or
array) on an `x-python-type` union. A `Literal` is read like a union of the types of its values (`str`, `bytes`, `int`,
`float` or `bool`, with the values of a nested `Literal` and without `None`), so `Literal[1, 2.5]` and
`Literal[1, None]` keep the number keywords in Pydantic models, while `Literal["a", 1]` and `Literal[True, False]` keep
none; `msgspec` accepts no constraint on a `Literal`. Custom templates receive the same values as the built-in ones.

A named schema whose `allOf` merges into one scalar type, such as
`{"allOf": [{"type": "string", "format": "duration"}, {"minimum": 0}]}`, is a root model of that type and follows the
same table.

```json
{
  "type": "object",
  "properties": {
    "count": {"type": "string", "x-python-type": "int", "minimum": 0},
    "wait": {"type": "string", "format": "duration", "minimum": 0},
    "at": {"type": "string", "format": "date-time", "minimum": 0},
    "day": {"type": "string", "format": "date", "minimum": 0}
  }
}
```

With `--field-constraints`:

```python
class Model(BaseModel):
    count: int | None = Field(None, ge=0)
    wait: timedelta | None = Field(None, ge=0)
    at: AwareDatetime | None = Field(None, ge=0)
    day: date | None = None
```

## 🔤 Which fields keep string and array keywords

`minLength`, `maxLength` and `pattern` hold for strings, and `minItems`, `maxItems` and `uniqueItems` hold for arrays.
They follow the same two cases as number keywords: a schema type `string` takes the string keywords and a schema type
`array` takes the array keywords; otherwise the Python type written for the field decides each keyword. A schema
without `type` is written as `Any`, which takes none of them, so `{"minLength": 2}` or `{"type": "integer",
"pattern": "^1"}` leaves the field unconstrained. For compatibility, a schema type `string` also writes `minItems` and
`maxItems`, and a schema type `array` also writes `minLength` and `maxLength`, as their length bounds. As for number
keywords, `msgspec.Struct` leaves out, with a warning, a keyword that msgspec does not accept on the Python type, such
as `pattern` on `bytes` or `minLength` on the `Literal` of a `const`.

A `typing` alias, an abstract collection, `Annotated[T, ...]`, `Final[T]` and `Literal` are read as for number
keywords, so `typing.List[int]`, `collections.abc.Sequence[int]` and `Annotated[list[int], ...]` take the keywords of
`list`, and `Literal["a", "bb", None]` and `Literal[b"a", b"bb"]` take those of `str` and `bytes` in Pydantic models.

| Python type | Pydantic | msgspec |
|-------------|----------|---------|
| `str`, `constr`, `StrictStr` | `minLength`, `maxLength`, `pattern` | `minLength`, `maxLength`, `pattern` |
| `bytes`, `StrictBytes` | `minLength`, `maxLength`, `pattern` | `minLength`, `maxLength` |
| `conbytes`, `EmailStr`, `SecretStr` | `minLength`, `maxLength` | none |
| `list`, `set`, `frozenset`, `tuple` and other sequences | `minItems`, `maxItems`, `uniqueItems`, `minLength`, `maxLength` | `minItems`, `maxItems`, `minLength`, `maxLength`, except on a fixed-length tuple such as `tuple[int, int]` |
| `deque` | `minItems`, `maxItems`, `uniqueItems`, `minLength`, `maxLength` | none |
| `collections.abc.Sized`, `Iterable`, `Generator` | `minItems`, `maxItems`, `uniqueItems`, `minLength`, `maxLength`; an iterable is checked while it is iterated | none |
| `typing.AnyStr`, `collections.abc.ByteString` | `minLength`, `maxLength`, `pattern` | none |
| a type the generator does not know or a model that the schema references | all of them | all of them |
| any other known type: `int`, `float`, `bool`, `None`, `Any`, dicts, other `typing` and `collections.abc` names such as `Container`, `Reversible` and `Buffer` | none | none |

```json
{
  "type": "object",
  "properties": {
    "code": {"type": "string", "minLength": 2},
    "any": {"minLength": 2},
    "count": {"type": "integer", "pattern": "^1"},
    "tags": {"items": {"type": "string"}, "minItems": 1, "pattern": "^a"}
  }
}
```

With `--field-constraints`:

```python
class Model(BaseModel):
    code: str | None = Field(None, min_length=2)
    any: Any | None = None
    count: int | None = None
    tags: list[str] | None = Field(None, min_length=1)
```

---

## 📖 See Also

- 🖥️ [CLI Reference: `--field-constraints`](cli-reference/field-customization.md#field-constraints) - Detailed CLI option documentation with examples
- 🔁 [Type Mappings](type-mappings.md) - Override schema types before field constraints are applied

## 🔗 Related Issues

- [pydantic/pydantic#156](https://github.com/pydantic/pydantic/issues/156)

---

# Field Aliases

Source: https://datamodel-code-generator.koxudaxi.dev/aliases/

<!-- related-cli-options: --aliases, --no-alias -->

# 🏷️ Field Aliases

The `--aliases` option allows you to rename fields in the generated models. This is useful when you want to use different Python field names than those defined in the schema while preserving the original names as serialization aliases.

## 🚀 Basic Usage

```bash
datamodel-codegen \
    --input schema.json \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py \
    --aliases aliases.json
```

You can also pass the same mapping inline:

```bash
datamodel-codegen \
    --input schema.json \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py \
    --aliases '{"id": "id_", "type": "type_"}'
```

## 📋 Alias Format

The alias JSON maps original field names to their Python aliases. Pass it either inline or as a JSON file path.

### 📝 Flat Format (Traditional)

The simplest format applies aliases to all fields with the matching name, regardless of which class they belong to:

```json
{
  "id": "id_",
  "type": "type_",
  "class": "class_"
}
```

This will rename all fields named `id` to `id_`, all fields named `type` to `type_`, etc.

### 🎯 Scoped Format (Class-Specific)

When you have the same field name in multiple classes but want different aliases for each, use the scoped format with `ClassName.field`:

```json
{
  "User.name": "user_name",
  "Address.name": "address_name",
  "name": "default_name"
}
```

**⚡ Priority**: Scoped aliases take priority over flat aliases. In the example above:

- `User.name` will be renamed to `user_name`
- `Address.name` will be renamed to `address_name`
- Any other class with a `name` field will use `default_name`

## 📝 Example

### 📥 Input Schema

```json
{
  "type": "object",
  "title": "Root",
  "properties": {
    "name": {"type": "string"},
    "user": {
      "type": "object",
      "title": "User",
      "properties": {
        "name": {"type": "string"},
        "id": {"type": "integer"}
      }
    },
    "address": {
      "type": "object",
      "title": "Address",
      "properties": {
        "name": {"type": "string"},
        "city": {"type": "string"}
      }
    }
  }
}
```

### 🏷️ Alias Mapping

```json
{
  "Root.name": "root_name",
  "User.name": "user_name",
  "Address.name": "address_name"
}
```

### ✨ Generated Output

```python
from pydantic import BaseModel, Field


class User(BaseModel):
    user_name: str | None = Field(None, alias="name")
    id: int | None = None


class Address(BaseModel):
    address_name: str | None = Field(None, alias="name")
    city: str | None = None


class Root(BaseModel):
    root_name: str | None = Field(None, alias="name")
    user: User | None = None
    address: Address | None = None
```

## 📌 Notes

- The `ClassName` in scoped format must match the generated Python class name (after title conversion)
- For `allOf` models, the final generated class name includes any configured prefix, suffix, or collision suffix. A matching final-name alias takes priority over a legacy alias using the original schema name; legacy aliases remain a fallback when no final-name alias is supplied.
- When using `--use-title-as-name`, the class name is derived from the `title` property in the schema
- Aliases are applied during code generation, so the original field names are preserved as Pydantic `alias` values for proper serialization/deserialization

---

## 📖 See Also

- 🖥️ [CLI Reference: `--aliases`](cli-reference/field-customization.md#aliases) - Detailed CLI option documentation with examples

---

# Field Validators

Source: https://datamodel-code-generator.koxudaxi.dev/validators/

<!-- related-cli-options: --validators -->

# Field Validators

The `--validators` option allows you to add custom field validators to generated Pydantic v2 models. This enables you to inject validation logic into generated code without manually editing it.

## Basic Usage

```bash
datamodel-codegen --input schema.json --output model.py \
  --validators validators.json \
  --use-annotated \
  --output-model-type pydantic_v2.BaseModel
```

You can also pass the same JSON object inline:

```bash
datamodel-codegen --input schema.json --output model.py \
  --validators '{"User":{"validators":[{"field":"name","function":"myapp.validators.validate_name"}]}}' \
  --use-annotated \
  --output-model-type pydantic_v2.BaseModel
```

## Validators Format

The validators JSON maps model names to their validator definitions. Pass it either inline or as a JSON file path.

### Structure

```json
{
  "ModelName": {
    "validators": [
      {
        "field": "field_name",
        "function": "module.path.to.validator_function",
        "mode": "after"
      }
    ]
  }
}
```

### Fields

| Field | Description | Required |
|-------|-------------|----------|
| `field` | Single field name to validate | One of `field` or `fields` |
| `fields` | List of field names (for multi-field validators) | One of `field` or `fields` |
| `function` | Fully qualified path to the validator function | Yes |
| `mode` | Validator mode: `before`, `after`, `wrap`, or `plain` | No (default: `after`) |

## Validator Modes

Pydantic v2 supports different validator modes, each with its own signature:

### `before` / `after` Mode

Standard validators that run before or after Pydantic's own validation:

```python
def validate_name(v: Any, info: ValidationInfo) -> Any:
    if not v:
        raise ValueError("Name cannot be empty")
    return v.strip()
```

### `wrap` Mode

Wrap validators receive a handler to call the next validator in the chain:

```python
from pydantic import ValidationInfo, ValidatorFunctionWrapHandler


def wrap_validate_name(v: Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo) -> Any:
    # Pre-processing
    v = v.strip() if isinstance(v, str) else v
    # Call next validator
    result = handler(v)
    # Post-processing
    return result.upper()
```

### `plain` Mode

Plain validators replace Pydantic's validation entirely:

```python
def plain_validate_name(v: Any) -> str:
    if not isinstance(v, str):
        raise TypeError("Expected string")
    return v
```

## Example

### Input Schema

```json
{
  "type": "object",
  "title": "User",
  "properties": {
    "name": {"type": "string"},
    "email": {"type": "string", "format": "email"},
    "age": {"type": "integer", "minimum": 0}
  },
  "required": ["name", "email"]
}
```

### Validators File

```json
{
  "User": {
    "validators": [
      {
        "field": "name",
        "function": "myapp.validators.validate_name",
        "mode": "before"
      },
      {
        "field": "email",
        "function": "myapp.validators.validate_email",
        "mode": "after"
      },
      {
        "fields": ["name", "email"],
        "function": "myapp.validators.validate_contact_info",
        "mode": "after"
      }
    ]
  }
}
```

### Validator Functions (myapp/validators.py)

```python
from typing import Any
from pydantic import ValidationInfo


def validate_name(v: Any, info: ValidationInfo) -> Any:
    if isinstance(v, str):
        return v.strip()
    return v


def validate_email(v: Any, info: ValidationInfo) -> Any:
    if isinstance(v, str) and not v.endswith("@example.com"):
        # Custom email domain validation
        pass
    return v


def validate_contact_info(v: Any, info: ValidationInfo) -> Any:
    # This runs for both name and email fields
    return v
```

### Generated Output

```python
from __future__ import annotations

from typing import Annotated, Any

from myapp.validators import validate_contact_info, validate_email, validate_name
from pydantic import BaseModel, EmailStr, Field, ValidationInfo, field_validator


class User(BaseModel):
    name: str
    email: EmailStr
    age: Annotated[int | None, Field(ge=0)] = None

    @field_validator("name", mode="before")
    @classmethod
    def validate_name_validator(cls, v: Any, info: ValidationInfo) -> Any:
        return validate_name(v, info)

    @field_validator("email", mode="after")
    @classmethod
    def validate_email_validator(cls, v: Any, info: ValidationInfo) -> Any:
        return validate_email(v, info)

    @field_validator("name", "email", mode="after")
    @classmethod
    def validate_contact_info_validator(cls, v: Any, info: ValidationInfo) -> Any:
        return validate_contact_info(v, info)
```

## Notes

- This feature only supports Pydantic v2 (`--output-model-type pydantic_v2.BaseModel`)
- The `ModelName` in the validators JSON must match the generated Python class name
- Validator functions are imported automatically based on the `function` path
- When validator method names collide with another validator, an existing field, or an inherited validator, an incrementing suffix (`_1`, `_2`, etc.) is added in registration order.
- Functions with the same name from different modules receive stable import aliases using the same suffix format. Repeated uses of the same function share its import binding; every validator registration is retained.

---

## See Also

- [CLI Reference: `--validators`](cli-reference/template-customization.md#validators) - CLI option documentation
- [Pydantic v2 Validators Documentation](https://docs.pydantic.dev/latest/concepts/validators/) - Official Pydantic documentation

---

# Custom Class Decorators

Source: https://datamodel-code-generator.koxudaxi.dev/class-decorators/

<!-- related-cli-options: --class-decorators, --additional-imports -->

# Custom Class Decorators

The `--class-decorators` option adds custom decorators to all generated model classes. This is useful for integrating with serialization libraries like `dataclasses_json`, or adding custom behavior to your models.

## Why use this?

When using `dataclasses.dataclass` output with `--snake-case-field`, Python field names are snake_case but the original JSON keys may be camelCase. Libraries like `dataclasses_json` can handle this conversion automatically via decorators.

## Example: Using dataclasses_json

Convert a JSON Schema with camelCase properties to dataclasses with snake_case fields that serialize back to camelCase.

**schema.json**
```json
{
  "type": "object",
  "title": "User",
  "properties": {
    "firstName": { "type": "string" },
    "lastName": { "type": "string" },
    "emailAddress": { "type": "string" }
  },
  "required": ["firstName", "lastName"]
}
```

### Without `--class-decorators`

```bash
datamodel-codegen --input schema.json \
  --output-model-type dataclasses.dataclass \
  --snake-case-field
```

**Generated model.py**
```python
from __future__ import annotations

from dataclasses import dataclass


@dataclass
class User:
    first_name: str
    last_name: str
    email_address: str | None = None
```

The field names are snake_case, but there's no way to map them back to the original camelCase JSON keys.

---

### With `--class-decorators`

```bash
datamodel-codegen --input schema.json \
  --output-model-type dataclasses.dataclass \
  --snake-case-field \
  --class-decorators "@dataclass_json(letter_case=LetterCase.CAMEL)" \
  --additional-imports "dataclasses_json.dataclass_json,dataclasses_json.LetterCase"
```

**Generated model.py**
```python
from __future__ import annotations

from dataclasses import dataclass

from dataclasses_json import LetterCase, dataclass_json


@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass
class User:
    first_name: str
    last_name: str
    email_address: str | None = None
```

Now serialization automatically converts between snake_case and camelCase:

```python
user = User(first_name="John", last_name="Doe")
print(user.to_json())
# {"firstName": "John", "lastName": "Doe", "emailAddress": null}
```

## Usage Notes

- **Multiple decorators**: Use comma separation for multiple decorators:
  ```bash
  --class-decorators "@decorator1,@decorator2"
  ```

- **@ prefix is optional**: Both `@dataclass_json` and `dataclass_json` work - the `@` is added automatically if missing.

- **Combine with `--additional-imports`**: Always add the required imports for your decorators using `--additional-imports`.

## Other Use Cases

The `--class-decorators` option works with any output model type:

- **Pydantic models**: Add custom validators or behavior
- **TypedDict**: Add runtime type-checking decorators
- **msgspec.Struct**: Add custom serialization hooks

## See Also

- [CLI Reference: `--class-decorators`](cli-reference/template-customization.md#class-decorators) - Detailed CLI option documentation
- [CLI Reference: `--additional-imports`](cli-reference/template-customization.md#additional-imports) - Adding custom imports

## Related Issues

- [#2358](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/2358) - Feature request for dataclasses_json support

---

# Custom Templates

Source: https://datamodel-code-generator.koxudaxi.dev/custom_template/

<!-- related-cli-options: --custom-template-dir, --extra-template-data -->

# 🎨 Custom Templates

One of the powerful features of datamodel-code-generator is the ability to use custom templates with the `--custom-template-dir` option. This allows you to provide a directory containing Jinja2 templates for customizing the generated code.

## 🚀 Usage

Pass the directory path containing your custom templates:

```bash
datamodel-codegen --input {your_input_file} --output {your_output_file} --custom-template-dir {your_custom_template_directory}
```

## 📝 Example

Let's say you want to generate a custom Python data model from a JSON Schema file called `person.json`. You want the generated data model to include a custom comment at the top of the file.

### 1️⃣ Create the template directory

Create a directory structure matching the output model type:

```
custom_templates/
└── pydantic/
    └── BaseModel.jinja2
```

### 2️⃣ Create the template

**custom_templates/pydantic/BaseModel.jinja2**
```jinja2
# This is a custom comment generated with custom_template!!

class {{ class_name }}({{ base_class }}):
{%- for field in fields %}
    {{ field.name }}: {{ field.type_hint }}
{%- endfor -%}
```

This custom template includes the custom comment at the top and replicates the default rendering behavior of the `BaseModel.jinja2` template.

### 3️⃣ Run the generator

```bash
datamodel-codegen --input person.json --output person.py --custom-template-dir custom_templates
```

### ✨ Generated Output

**person.py**
```python
# generated by datamodel-codegen:
#   filename:  person.json
#   timestamp: 2023-04-09T05:36:24+00:00

from __future__ import annotations

from typing import Optional

from pydantic import BaseModel

# This is a custom comment generated with custom_template!!


class Model(BaseModel):
    name: Optional[str]
    age: Optional[int]
```

## 📚 Template Reference

You can create more complex custom templates by copying [the default templates](https://github.com/datamodel-code-generator/datamodel-code-generator/tree/main/src/datamodel_code_generator/model/template). Use them as a reference for understanding the structure and available variables, and customize the code generation process according to your specific requirements.

---

## 🔧 Schema Extensions

OpenAPI and JSON Schema allow custom extension fields prefixed with `x-`. These schema extensions are automatically passed to templates via the `extensions` variable, enabling dynamic code generation based on your custom schema metadata.

### Example: Database Model Configuration

Suppose you want to add a `__collection__` class attribute based on a custom `x-database-model` extension in your OpenAPI schema:

**api.yaml**
```yaml
openapi: "3.0.0"
info:
  version: 1.0.0
  title: My API
paths: {}
components:
  schemas:
    User:
      type: object
      x-database-model:
        collection: users
        indexes:
          - email
      properties:
        id:
          type: string
        email:
          type: string
      required:
        - id
        - email
```

**custom_templates/pydantic_v2/BaseModel.jinja2**
```jinja2
class {{ class_name }}({{ base_class }}):
{%- if extensions is defined and extensions.get('x-database-model') %}
    __collection__ = "{{ extensions['x-database-model']['collection'] }}"
{%- endif %}
{%- for field in fields %}
    {{ field.name }}: {{ field.type_hint }}
{%- endfor %}
```

**Run the generator**
```bash
datamodel-codegen --input api.yaml --output models.py \
    --custom-template-dir custom_templates \
    --output-model-type pydantic_v2.BaseModel
```

**Generated Output**
```python
from __future__ import annotations

from pydantic import BaseModel


class User(BaseModel):
    __collection__ = "users"
    id: str
    email: str
```

### Available Extensions

Any field starting with `x-` in your schema will be available in the `extensions` dictionary:

| Schema Field | Template Access |
|--------------|-----------------|
| `x-database-model` | `extensions['x-database-model']` |
| `x-custom-flag` | `extensions['x-custom-flag']` |
| `x-my-extension` | `extensions['x-my-extension']` |

### Use Cases

- **Database mapping**: Add collection names, indexes, or ORM configurations
- **Validation rules**: Include custom validation logic based on schema metadata
- **Documentation**: Generate custom docstrings or comments from schema extensions
- **Framework integration**: Add framework-specific decorators or attributes

---

## 📖 See Also

- 🖥️ [CLI Reference: `--custom-template-dir`](cli-reference/template-customization.md#custom-template-dir) - Detailed CLI option documentation
- 📊 [CLI Reference: `--extra-template-data`](cli-reference/template-customization.md#extra-template-data) - Pass custom variables to templates

---

# Custom Code Formatters

Source: https://datamodel-code-generator.koxudaxi.dev/custom-formatters/

<!-- related-cli-options: --custom-formatters, --custom-formatters-kwargs -->

# 🎨 Custom Code Formatters

Create your own custom code formatters for specialized formatting needs.

## 🚀 Usage

Pass the module path containing your formatter class:

```bash
datamodel-codegen --input {your_input_file} --output {your_output_file} --custom-formatters "{path_to_your_module}.your_module"
```

## 📝 Example

### 1️⃣ Create your formatter

### your_module.py

```python
from datamodel_code_generator.format import CustomCodeFormatter


class CodeFormatter(CustomCodeFormatter):
    def apply(self, code: str) -> str:
        # Apply your custom formatting here
        # For example, add a custom header comment:
        header = "# This code was formatted by custom formatter\n"
        return header + code
```

### 2️⃣ Use your formatter

```bash
datamodel-codegen --input schema.json --output model.py --custom-formatters "mypackage.your_module"
```

## 🔧 Passing Arguments

You can pass keyword arguments to your custom formatter using `--custom-formatters-kwargs`:

```bash
datamodel-codegen --input schema.json --output model.py \
    --custom-formatters "mypackage.your_module" \
    --custom-formatters-kwargs '{"line_length": 100}'
```

---

## 📖 See Also

- 🖥️ [CLI Reference: `--custom-formatters`](cli-reference/template-customization.md#custom-formatters) - Detailed CLI option documentation
- 🔧 [CLI Reference: `--custom-formatters-kwargs`](cli-reference/template-customization.md#custom-formatters-kwargs) - Pass arguments to custom formatters
- 🖌️ [Formatting](formatting.md) - Built-in code formatting with black and isort

---

# Code Formatting

Source: https://datamodel-code-generator.koxudaxi.dev/formatting/

<!-- related-cli-options: --formatters -->

# 🖌️ Code Formatting

Generated code is automatically formatted using code formatters. By default, `black` and `isort` are used to produce consistent, well-formatted output.

!!! warning "Experimental"
    The built-in formatter (`--formatters builtin`) is experimental and may change as generated-output coverage is
    expanded.

This page is a practical guide for choosing and configuring formatters. For the exact built-in formatter scope and
configuration precedence, see [Formatter Behavior](formatter-behavior.md).

## 🎯 Default Behavior

!!! warning "Future Change"
    In a future version, builtin will become the default to reduce required installation dependencies and
    version constraints. Black/isort remain the default and required dependencies today.

    **CLI users**: Select `--formatters` or a new preset that supplies formatters to suppress the default-change warning, or use `--disable-warnings`.

    **Library users**: Explicitly pass `formatters` or a preset that supplies formatters. Older presets retain the default-change warning.

```bash
datamodel-codegen \
    --input schema.yaml \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

This runs the following formatters in order:

1. **isort** - Sorts and organizes imports
2. **black** - Formats code style

## 🛠️ Available Formatters

| Formatter | Description |
|-----------|-------------|
| `builtin` | Dependency-free formatter for generated code |
| `black` | Code formatting (PEP 8 style) |
| `isort` | Import sorting |
| `ruff-check` | Linting with auto-fix |
| `ruff-format` | Fast code formatting (black alternative) |

### Choose a formatter

Choose a formatter to match your project and generation priorities:

- **Projects using Ruff:** use `--formatters ruff-check ruff-format` to keep generated code consistent with the
  project's formatting and lint policy. Install it with `pip install 'datamodel-code-generator[ruff]'`.
- **No Ruff, Black, or isort, or generation speed is the priority:** use `--formatters builtin` to avoid running
  external formatters on standard generated model modules.
- **Projects using Black/isort:** keep `--formatters black isort` to 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.

Custom templates can emit Python outside the standard generated model patterns covered by `builtin`, so
custom-template output is not exhaustively validated. If `--formatters builtin` produces invalid or poorly formatted
output with a custom template, please open an issue with a small reproducer.

### Using the built-in formatter

The built-in formatter is designed for code generated by this project. It does not require external formatter dependencies. It formats the leading import block and applies basic whitespace cleanup. It is not a full replacement for Black, isort, or Ruff on arbitrary Python code.
It is used as an alternative to external formatters. If `builtin` is passed together with `black`, `isort`, `ruff-check`, or `ruff-format`, the built-in formatter is ignored.

```bash
datamodel-codegen \
    --formatters builtin \
    --input schema.yaml \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

See [Formatter Behavior](formatter-behavior.md) for the exact built-in formatter scope and configuration precedence.

If you use `--custom-template-dir`, review the built-in formatter scope before selecting `builtin`. Custom templates can
generate Python outside the supported model patterns, so custom-template output is not exhaustively validated with the
built-in formatter. If `--formatters builtin` produces invalid or poorly formatted output with a custom template, please
open an issue with a small reproducer.

### ⚡ Using ruff instead of black

[Ruff](https://github.com/astral-sh/ruff) is a fast Python linter and formatter. To use it:

!!! note "Installation Required"
    ruff is an optional dependency. Install it with:
    ```bash
    pip install 'datamodel-code-generator[ruff]'
    ```

```bash
# Use ruff for both linting and formatting
datamodel-codegen \
    --formatters ruff-check ruff-format \
    --input schema.yaml \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py

# Use ruff-format as a black replacement
datamodel-codegen \
    --formatters isort ruff-format \
    --input schema.yaml \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

### 🚫 Disable formatting

`datamodel-codegen` requires at least one formatter when using the CLI `--formatters` option.

To disable built-in formatting entirely, configure it via `pyproject.toml`:

```toml title="pyproject.toml"
[tool.datamodel-codegen]
formatters = []
```

## ⚙️ Configuration via pyproject.toml

Formatters read their configuration from `pyproject.toml`. The effective search path starts from the output path directory, or the current working directory when no output path is available, and then checks parent directories.

The built-in formatter uses line length for import wrapping and generated model statement wrapping. Its precedence is:

1. API `builtin_format_line_length`
2. `[tool.datamodel-codegen].builtin-format-line-length` or `[tool.datamodel-codegen].builtin_format_line_length`
3. `[tool.ruff].line-length`
4. `[tool.black].line-length`
5. `[tool.isort].line_length`
6. `88`

### 📝 Example Configuration

```toml title="pyproject.toml"
[tool.datamodel-codegen]
formatters = ["builtin"]
builtin-format-line-length = 100

[tool.black]
line-length = 100
skip-string-normalization = true

[tool.isort]
profile = "black"
line_length = 100

[tool.ruff]
line-length = 100

[tool.ruff.format]
quote-style = "single"
```

## 💬 String Quotes

By default, string quote style is determined by your formatter configuration. To force double quotes regardless of configuration:

```bash
datamodel-codegen \
    --use-double-quotes \
    --input schema.yaml \
    --output-model-type pydantic_v2.BaseModel \
    --output model.py
```

This overrides `skip_string_normalization` in black config.
When using `--formatters builtin` without `--use-double-quotes`, the built-in formatter also reads `[tool.black].skip-string-normalization`. Set it to `false` to normalize simple generated string literals to double quotes.

## 🎨 Custom Formatters

You can create custom formatters for specialized formatting needs. See [Custom Formatters](custom-formatters.md) for details.

---

## 📖 See Also

- 🖌️ [Formatter Behavior](formatter-behavior.md) - Built-in formatter scope and configuration precedence
- 🖥️ [CLI Reference: `--formatters`](cli-reference/template-customization.md#formatters) - Specify code formatters
- 💬 [CLI Reference: `--use-double-quotes`](cli-reference/template-customization.md#use-double-quotes) - Force double quotes
- 🎨 [Custom Formatters](custom-formatters.md) - Create your own formatters
- ⚙️ [pyproject.toml Configuration](pyproject_toml.md) - Configure datamodel-codegen options

## Dependency migration

See [Dependency migration notices](dependency-migration.md) for Black/isort extras, separate optional-installation
and old-version warnings, unchanged current requirements, and the distinction between DCG runtime Pydantic and
generated-code compatibility. Old presets without formatters retain the implicit-default warning.

---

# Formatter behavior

Source: https://datamodel-code-generator.koxudaxi.dev/formatter-behavior/

<!-- related-cli-options: --formatters -->

# Formatter behavior

`datamodel-codegen` formats generated Python code after model generation. The default formatter list is currently `black` and `isort`.

!!! warning "Experimental"
    The built-in formatter (`--formatters builtin`) is experimental and may change as generated-output coverage is
    expanded.

This page is the reference for the built-in formatter's exact scope and precedence. For a formatter selection guide,
see [Code Formatting](formatting.md).

This default will change in a future release. The default formatter will become `builtin`, and external formatter
dependencies will become opt-in so that generated output can be produced without installing formatter packages.

## Formatter selection

Use `--formatters` to select the formatter pipeline.

```bash
datamodel-codegen \
    --input schema.yaml \
    --output model.py \
    --formatters builtin
```

Available formatter names are:

| Name | Behavior |
| ---- | -------- |
| `builtin` | Internal formatter for generated model modules. No external package is required. |
| `black` | Runs Black against generated code. |
| `isort` | Runs isort against generated imports. |
| `ruff-check` | Runs `ruff check --fix`. |
| `ruff-format` | Runs `ruff format`. |

`--formatters` selects which formatter integrations are enabled. It does not reorder the built-in integrations:
single-file output is processed as isort, built-in formatter, Black, then Ruff check/format when those formatters are
selected.
The built-in formatter is an alternative to external formatting, not a pre-formatter.
If `builtin` is passed together with `black`, `isort`, `ruff-check`, or `ruff-format`, `builtin` is ignored.

### Choose a formatter

Choose a formatter to match your project and generation priorities:

- **Projects using Ruff:** use `--formatters ruff-check ruff-format` to keep generated code consistent with the
  project's formatting and lint policy. Install it with `pip install 'datamodel-code-generator[ruff]'`.
- **No Ruff, Black, or isort, or generation speed is the priority:** use `--formatters builtin` to avoid running
  external formatters on standard generated model modules.
- **Projects using Black/isort:** keep `--formatters black isort` to 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.

Custom templates can emit Python outside the standard generated model patterns covered by `builtin`, so
custom-template output is not exhaustively validated. If `--formatters builtin` produces invalid or poorly formatted
output with a custom template, please open an issue with a small reproducer.

## Built-in formatter scope

The built-in formatter is intentionally small. It is not a general Python formatter and is not expected to produce byte-for-byte identical output to the latest Black, isort, or Ruff for arbitrary Python files.

It covers the generated-code patterns that matter for model modules:

- Removes trailing whitespace and writes a final newline.
- Parses the module with `ast`.
- Sorts only the leading import block. It stops at the first non-import statement.
- Splits `import a, b` into separate `import` lines.
- Groups imports in this order: `__future__`, standard library, third-party, relative imports.
- Sorts `from ... import ...` names and merges imports from the same module.
- Wraps long `from ... import ...` statements with parentheses when they exceed the configured line length.
- Leaves commented import lines in place instead of dropping comments while sorting imports.
- Sorts imports inside a top-level `if TYPE_CHECKING:` block when that block contains only imports.
- Keeps two blank lines before a top-level `class`, `def`, or `async def` after the import block.
- Wraps generated model statements for common long `Field(...)`, `Annotated[...]`, and `ConfigDict(...)` lines.
- Normalizes simple generated string quotes to double quotes when `--use-double-quotes` is passed or `[tool.black].skip-string-normalization = false`.

If the generated code cannot be parsed as Python, the built-in formatter only applies whitespace cleanup and returns the code.

The built-in formatter does not currently format:

- General expressions inside classes or functions.
- List, dict, tuple, or arbitrary call argument layout outside the generated model patterns listed above.
- General quote style rewrites outside simple generated strings.
- String wrapping outside supported generated call arguments.
- Comment placement beyond preserving commented import lines.
- Import section rules beyond the simple groups listed above.

This scope matters when using `--custom-template-dir`. Custom templates can emit arbitrary Python code outside the
generated model patterns listed above, so custom-template output is not exhaustively validated with the built-in
formatter. If `--formatters builtin` produces invalid or poorly formatted output with a custom template, please open an
issue with a small reproducer.

For exact Black, isort, or Ruff behavior, continue to pass those formatters explicitly.
The built-in formatter is not run before external formatters.

## Line length

The built-in formatter uses line length for wrapping `from ... import ...` statements and the generated model
statements listed above.

Set it in `pyproject.toml`:

```toml
[tool.datamodel-codegen]
formatters = ["builtin"]
builtin-format-line-length = 100
```

The built-in formatter uses line length in this order:

1. API `builtin_format_line_length`
2. `[tool.datamodel-codegen].builtin-format-line-length` or `[tool.datamodel-codegen].builtin_format_line_length`
3. `[tool.ruff].line-length`
4. `[tool.black].line-length`
5. `[tool.isort].line_length`
6. `88`

The fallback formatter settings only read configuration values. They do not require Ruff, Black, or isort to be
installed.

## String normalization

The built-in formatter keeps single quotes by default. It normalizes simple generated string literals to double quotes when either condition is true:

1. `--use-double-quotes` is passed.
2. `[tool.black].skip-string-normalization = false` is set in `pyproject.toml`.

The built-in formatter only reads this Black setting when `builtin` is selected without an external formatter.

## API usage

Library users can pass the same setting through `generate()` or `GenerateConfig`.

```python
from pathlib import Path

from datamodel_code_generator import generate
from datamodel_code_generator.format import Formatter

generate(
    input_=Path("schema.yaml"),
    output=Path("model.py"),
    formatters=[Formatter.BUILTIN],
    builtin_format_line_length=100,
)
```

## Migration notes

To keep current output behavior, set the external formatters explicitly:

```bash
datamodel-codegen \
    --input schema.yaml \
    --output model.py \
    --formatters black isort
```

To test the dependency-free path, use:

```bash
datamodel-codegen \
    --input schema.yaml \
    --output model.py \
    --formatters builtin
```

Generated output may differ from Black or isort output in places outside the built-in formatter scope. Treat those differences as expected unless they change Python semantics or produce invalid code.

## Dependency migration

See [Dependency migration notices](dependency-migration.md) for Black/isort extras, separate optional-installation
and old-version warnings, unchanged current requirements, and the distinction between DCG runtime Pydantic and
generated-code compatibility. Old presets without formatters retain the implicit-default warning.

---

# One-liner Usage

Source: https://datamodel-code-generator.koxudaxi.dev/oneliner/

This guide covers how to use datamodel-code-generator with pipes and clipboard tools for quick, one-time code generation without permanent installation.

!!! note
    The package name is `datamodel-code-generator`, and the CLI command is `datamodel-codegen`.
    Because the names differ, pass the package explicitly with `uvx --from` or `pipx run --spec`.

---

## One-liner Execution with uvx/pipx

You don't need to install datamodel-code-generator permanently. Use `uvx` or `pipx run` to execute it directly.

### Using uvx (Recommended)

[uvx](https://docs.astral.sh/uv/guides/tools/) runs Python tools without installation:

```bash
# Basic usage
uvx --from datamodel-code-generator datamodel-codegen --input schema.json --output model.py

# With extras (e.g., HTTP support)
uvx --from 'datamodel-code-generator[http]' datamodel-codegen --url https://example.com/api.yaml --output model.py

# With GraphQL support
uvx --from 'datamodel-code-generator[graphql]' datamodel-codegen --input schema.graphql --output model.py
```

### Using pipx run

[pipx](https://pipx.pypa.io/) also supports one-shot execution:

```bash
pipx run --spec datamodel-code-generator datamodel-codegen --input schema.json --output model.py
```

---

## Reading from stdin

datamodel-code-generator can read schema input from stdin, enabling powerful pipeline workflows:

```bash
# Pipe JSON directly
echo '{"type": "object", "properties": {"name": {"type": "string"}}}' | \
  uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema

# Pipe from another command
curl -s https://example.com/schema.json | \
  uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema --output model.py
```

---

## Clipboard Integration

Combine stdin support with clipboard tools to quickly generate models from copied schema definitions.

### macOS (pbpaste/pbcopy)

```bash
# Generate from clipboard and print to stdout
pbpaste | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema

# Generate from clipboard and save to file
pbpaste | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema --output model.py

# Generate from clipboard and copy result back to clipboard
pbpaste | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema | pbcopy
```

### Linux (xclip/xsel)

=== "xclip"

    ```bash
    # Generate from clipboard and print to stdout
    xclip -selection clipboard -o | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema

    # Generate and copy result to clipboard
    xclip -selection clipboard -o | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema | xclip -selection clipboard
    ```

=== "xsel"

    ```bash
    # Generate from clipboard and print to stdout
    xsel --clipboard --output | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema

    # Generate and copy result to clipboard
    xsel --clipboard --output | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema | xsel --clipboard --input
    ```

!!! tip "Installing clipboard tools on Linux"
    ```bash
    # Debian/Ubuntu
    sudo apt install xclip
    # or
    sudo apt install xsel

    # Fedora
    sudo dnf install xclip
    # or
    sudo dnf install xsel
    ```

### Windows (clip/PowerShell)

=== "PowerShell"

    ```powershell
    # Generate from clipboard and print to stdout
    Get-Clipboard | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema

    # Generate and copy result to clipboard
    Get-Clipboard | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema | Set-Clipboard
    ```

=== "Command Prompt"

    ```batch
    REM Windows Command Prompt doesn't have a built-in paste command
    REM Use PowerShell from cmd:
    powershell -command "Get-Clipboard" | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema
    ```

!!! note "Windows clip command"
    The `clip` command on Windows only supports copying **to** the clipboard, not reading from it. Use PowerShell's `Get-Clipboard` and `Set-Clipboard` for full clipboard integration.

---

## Practical Examples

### Quick model generation workflow

1. Copy a JSON Schema from documentation or an API response
2. Run the generator from clipboard:

```bash
# macOS
pbpaste | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel

# Linux
xclip -selection clipboard -o | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel

# Windows PowerShell
Get-Clipboard | uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel
```

### Generating from API documentation

```bash
# Fetch OpenAPI spec and generate models
curl -s https://petstore3.swagger.io/api/v3/openapi.json | \
  uvx --from datamodel-code-generator datamodel-codegen --input-file-type openapi --output-model-type pydantic_v2.BaseModel --output petstore.py
```

### Generating from GitHub raw URLs

You can directly fetch schemas from GitHub repositories using raw URLs:

```bash
# Fetch JSON Schema from GitHub and generate models
curl -s https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.0/schema.json | \
  uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel

# Fetch OpenAPI spec from a GitHub repository
curl -s https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json | \
  uvx --from datamodel-code-generator datamodel-codegen --input-file-type openapi --output-model-type pydantic_v2.BaseModel --output github_api.py
```

!!! tip "Using the --url option"
    If you have the `http` extra installed, you can use `--url` directly without curl:

    ```bash
    uvx --from 'datamodel-code-generator[http]' datamodel-codegen \
      --url https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.0/schema.json \
      --input-file-type jsonschema \
      --output-model-type pydantic_v2.BaseModel
    ```

### Using with jq for JSON manipulation

```bash
# Extract a specific schema definition and generate a model
cat openapi.yaml | yq '.components.schemas.User' | \
  uvx --from datamodel-code-generator datamodel-codegen --input-file-type jsonschema
```

---

## Comparison: Installation Methods

| Method | Command | Use Case |
|--------|---------|----------|
| **uvx** | `uvx --from datamodel-code-generator datamodel-codegen` | One-liner usage, no installation |
| **pipx run** | `pipx run --spec datamodel-code-generator datamodel-codegen` | One-liner usage, alternative to uvx |
| **uv tool install** | `uv tool install datamodel-code-generator` | Standalone CLI installation |
| **pipx install** | `pipx install datamodel-code-generator` | Global installation, frequent usage |
| **uv add --dev** | `uv add --dev datamodel-code-generator` | Pinned project/CI dependency |
| **pip install** | `pip install datamodel-code-generator` | Traditional installation |

!!! tip "When to use each method"
    - **uvx/pipx run**: Quick one-liner generation, testing different versions
    - **uv tool install/pipx install**: Frequent CLI usage across multiple projects
    - **uv add --dev/pip install**: Project dependency, CI/CD pipelines, programmatic usage

---

# Using datamodel-code-generator as a Module

Source: https://datamodel-code-generator.koxudaxi.dev/using_as_module/

datamodel-code-generator is a CLI tool, but it can also be used as a Python module.

## 🚀 How to Use

You can generate models with `datamodel_code_generator.generate` using parameters that match the [CLI arguments](./index.md).

### 📦 Installation

The base package is sufficient when all inputs and references are local. To
load an HTTP(S) input or resolve a remote `$ref`, install the stable HTTP extra:

```bash
pip install 'datamodel-code-generator[http]'
```

The `http` extra uses HTTPX and is supported and not deprecated. The
experimental HTTPX2 backend is available separately:

```bash
pip install 'datamodel-code-generator[httpx2]'
```

The experimental extra is not included in `datamodel-code-generator[all]`.
The default `HTTPBackend.AUTO` policy selects stable HTTPX when its client
module is installed, including when both extras are installed, and selects
HTTPX2 only when that module is absent. Require HTTPX2 with
`--http-backend httpx2`, `http_backend = "httpx2"` under
`[tool.datamodel-codegen]`, or the public API:

```python
from urllib.parse import urlparse

from datamodel_code_generator import HTTPBackend, generate

result = generate(
    urlparse("https://example.com/schema.json"),
    http_backend=HTTPBackend.HTTPX2,
)
```

See [HTTP backend selection](faq.md#http-backend-selection) for the complete
automatic and explicit selection rules.

### 📝 Getting Generated Code as String

When the `output` parameter is omitted (or set to `None`), `generate()` returns the generated code directly as a string:

!!! note
    `GenerateConfig` requires a Pydantic v2 environment.

```python
from datamodel_code_generator import InputFileType, generate, GenerateConfig, DataModelType

json_schema: str = """{
    "type": "object",
    "properties": {
        "number": {"type": "number"},
        "street_name": {"type": "string"},
        "street_type": {"type": "string",
                        "enum": ["Street", "Avenue", "Boulevard"]
                        }
    }
}"""

config = GenerateConfig(
    input_file_type=InputFileType.JsonSchema,
    input_filename="example.json",
    output_model_type=DataModelType.PydanticV2BaseModel,
)
result = generate(json_schema, config=config)
print(result)
```

### Loading Project Configuration

`generate()` uses the options passed to it. The settings the command line implies
apply the same way: `msgspec.Struct` output turns on `use_annotated` unless it is
passed, and `use_annotated` turns on `field_constraints`. Pass
`use_annotated=False` to keep msgspec models without `Annotated` constraints, as
`generate()` wrote them before 0.84.0.

To reuse `[tool.datamodel-codegen]` from `pyproject.toml`, explicitly load a
`GenerateConfig`:

```python
from datamodel_code_generator import generate, load_pyproject_config

config = load_pyproject_config()
result = generate(json_schema, config=config)
```

The loader searches upward from the working directory, stopping at a Git project
boundary, as the CLI does. Pass `path="project"`, a `Path`, or a `pyproject.toml` path
to start elsewhere, and `profile="models"` to select a profile, including its
`extends` inheritance. Without project settings, it returns the API defaults;
a requested profile must exist.

Both a `GenerateConfig` and a dictionary of individual Python API options can
override the project settings:

```python
from datamodel_code_generator import GenerateConfig, InputFileType

options = {"input_file_type": InputFileType.JsonSchema, "output": None}
config = load_pyproject_config(overrides=options)
result = generate(json_schema, config=config)

existing_config = GenerateConfig(output=None, disable_timestamp=True)
config = load_pyproject_config(profile="models", overrides=existing_config)
result = generate(json_schema, config=config)
```

The precedence is API defaults, project settings, profile settings, then
overrides. Only explicitly set fields of a `GenerateConfig` override are merged;
explicit `False`, `None`, and empty lists also replace project values. Paths
loaded from TOML are relative to its directory, including JSON configuration
files such as `aliases`, unlike the command line, which reads those JSON files
from the working directory. Override paths remain relative to the caller's
working directory. The project directory supplies formatter settings unless
`settings_path` is explicitly overridden. CLI-only settings such as `input`,
`check`, and batch jobs are ignored: pass the schema to `generate()` yourself.
The loader validates the merged settings and preserves the existing rule that
`config=` cannot be combined with individual `generate()` options.

### 📝 Reading Input From a File

Pass a `Path` to `input_` for file input. Plain strings are treated as schema
text; if a string points to an existing file and parsing fails, `generate()`
warns and recommends using `Path`.

```python
from pathlib import Path

from datamodel_code_generator import InputFileType, generate

result = generate(
    input_=Path("example.json"),
    input_file_type=InputFileType.JsonSchema,
)
print(result)
```

### 📝 Multiple Module Output

When the schema generates multiple modules, `generate()` returns a `GeneratedModules` dictionary mapping module path tuples to generated code:

```python
from datamodel_code_generator import InputFileType, generate, GenerateConfig, GeneratedModules

# Your OpenAPI specification (string schema text, Path, or dict)
openapi_spec: str = "..."  # Replace with your actual OpenAPI spec

# Schema that generates multiple modules (e.g., with $ref to other files)
config = GenerateConfig(
    input_file_type=InputFileType.OpenAPI,
)
result: str | GeneratedModules = generate(openapi_spec, config=config)

if isinstance(result, dict):
    for module_path, content in result.items():
        print(f"Module: {'/'.join(module_path)}")
        print(content)
        print("---")
else:
    print(result)
```

### 📝 Writing to Files

To write generated code to the file system, provide a `Path` to the `output` parameter in the config:

```python
from pathlib import Path
from tempfile import TemporaryDirectory
from datamodel_code_generator import InputFileType, generate, GenerateConfig, DataModelType

json_schema: str = """{
    "type": "object",
    "properties": {
        "number": {"type": "number"},
        "street_name": {"type": "string"},
        "street_type": {"type": "string",
                        "enum": ["Street", "Avenue", "Boulevard"]
                        }
    }
}"""

with TemporaryDirectory() as temporary_directory_name:
    temporary_directory = Path(temporary_directory_name)
    output = Path(temporary_directory / "model.py")
    config = GenerateConfig(
        input_file_type=InputFileType.JsonSchema,
        input_filename="example.json",
        output=output,
        # set up the output model types
        output_model_type=DataModelType.PydanticV2BaseModel,
    )
    generate(json_schema, config=config)
    model: str = output.read_text()
print(model)
```

**✨ Output:**
```python
# generated by datamodel-codegen:
#   filename:  example.json
#   timestamp: 2020-12-21T08:01:06+00:00

from __future__ import annotations

from enum import Enum
from typing import Optional

from pydantic import BaseModel


class StreetType(Enum):
    Street = "Street"
    Avenue = "Avenue"
    Boulevard = "Boulevard"


class Model(BaseModel):
    number: Optional[float] = None
    street_name: Optional[str] = None
    street_type: Optional[StreetType] = None
```

---

### Generating a Server or Client Package

!!! warning "Experimental"
    Server and client generation is experimental; its options and generated packages may change.

`generate()` also generates the [FastAPI server](fastapi-server.md) or the [HTTPX2 client](python-client.md) package
of an OpenAPI document together with its models. `generate_server` or `generate_client` selects the package, and
the `server_*` or `client_*` options configure it. They are the options of `--generate-server`, `--generate-client`,
and the `--server-*` and `--client-*` flags under their Python names, as for model options: choices are enums such as
`ServerType` (their string values also work), and the options that take JSON on the command line take mappings.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: using-as-module.server -->
<!-- fmt: off -->

```python
from pathlib import Path

from datamodel_code_generator import (
    DataModelType,
    InputFileType,
    OpenAPIScope,
    ServerHandlerMode,
    ServerType,
    generate,
)

generate(
    Path("openapi.yaml"),
    input_file_type=InputFileType.OpenAPI,
    openapi_scopes=[OpenAPIScope.Schemas, OpenAPIScope.Api],
    output_model_type=DataModelType.PydanticV2BaseModel,
    preset="standard-py312-20261015",
    output=Path("app/models.py"),
    generate_server=ServerType.FastAPI,
    server_output=Path("app/server"),
    server_package="app.server",
    server_model_package="app.models",
    server_handler_mode=ServerHandlerMode.Async,
    server_body_modes={"/paths/~1upload/post": "request"},
)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: using-as-module.server -->

With an `output`, `generate()` writes the models and the package together and returns `None`; for a server, it also
writes each missing module of the `services` package beside the package once, with stubs, as the command line does.
Without one, it writes nothing but the model metadata and a remote lock update, no stubs among them, and returns
`GeneratedModules` with every model and package file, each under the path its import path implies: `server_model_package="app.models"` gives `("app", "models.py")`, or
`("app", "models", "__init__.py")` and the other modules of modular models, and `server_package="app.server"` gives
`("app", "server", "application.py")`, `("app", "server", "README.md")`, and so on. These are the files a run with `output` and
`server_output` in the working directory writes; `server_output` is not used. The run renders the files in a private
directory of the working directory, which it removes afterwards, so the working directory must be writable. `load_pyproject_config()` takes the
server and client keys of `pyproject.toml` too, so a config it loads with `overrides={"output": None}` returns the
files of the configured run.

The selector requires `server_package` and `server_model_package` (or the client ones), and `server_output` with an
`output`. A model setting the target needs that neither the arguments nor the preset set, such as `openapi_scopes` or
`target_python_version`, takes the value the target needs, without printing anything; see
[Requirements](fastapi-server.md#requirements). A missing option, an option the target cannot use, and a failure of the package raise
`datamodel_code_generator.Error` with the message the command line prints. The `server_*` and `client_*` options have
no effect without their selector, as their `pyproject.toml` keys do.

---

## 🔧 Using the Parser Directly

You can also call the parser directly for more control. Parser classes also support the `config` parameter similar to `generate()`.

### Using `config` Parameter (Recommended)

```python
from datamodel_code_generator import DataModelType, PythonVersion
from datamodel_code_generator.config import JSONSchemaParserConfig
from datamodel_code_generator.model import get_data_model_types
from datamodel_code_generator.parser.jsonschema import JsonSchemaParser

json_schema: str = """{
    "type": "object",
    "properties": {
        "number": {"type": "number"},
        "street_name": {"type": "string"},
        "street_type": {"type": "string",
                        "enum": ["Street", "Avenue", "Boulevard"]
                        }
    }
}"""

data_model_types = get_data_model_types(DataModelType.PydanticV2BaseModel, target_python_version=PythonVersion.PY_311)
config = JSONSchemaParserConfig(
    data_model_type=data_model_types.data_model,
    data_model_root_type=data_model_types.root_model,
    data_model_field_type=data_model_types.field_model,
    data_type_manager_type=data_model_types.data_type_manager,
    dump_resolve_reference_action=data_model_types.dump_resolve_reference_action,
)
parser = JsonSchemaParser(json_schema, config=config)
result = parser.parse()
print(result)
```

### Using Keyword Arguments (Backward Compatible)

```python
from datamodel_code_generator import DataModelType, PythonVersion
from datamodel_code_generator.model import get_data_model_types
from datamodel_code_generator.parser.jsonschema import JsonSchemaParser

json_schema: str = """{
    "type": "object",
    "properties": {
        "number": {"type": "number"},
        "street_name": {"type": "string"},
        "street_type": {"type": "string",
                        "enum": ["Street", "Avenue", "Boulevard"]
                        }
    }
}"""

data_model_types = get_data_model_types(DataModelType.PydanticV2BaseModel, target_python_version=PythonVersion.PY_311)
parser = JsonSchemaParser(
    json_schema,
    data_model_type=data_model_types.data_model,
    data_model_root_type=data_model_types.root_model,
    data_model_field_type=data_model_types.field_model,
    data_type_manager_type=data_model_types.data_type_manager,
    dump_resolve_reference_action=data_model_types.dump_resolve_reference_action,
)
result = parser.parse()
print(result)
```

### Available Parser Config Classes

Each parser type has its own config class:

| Parser | Config Class |
|--------|-------------|
| `JsonSchemaParser` | `JSONSchemaParserConfig` |
| `OpenAPIParser` | `OpenAPIParserConfig` |
| `AvroParser` | `AvroParserConfig` |
| `GraphQLParser` | `GraphQLParserConfig` |

All config classes inherit from `ParserConfig` and include additional parser-specific options.

**✨ Output:**
```python
from __future__ import annotations

from enum import Enum
from typing import Optional

from pydantic import BaseModel


class StreetType(Enum):
    Street = "Street"
    Avenue = "Avenue"
    Boulevard = "Boulevard"


class Model(BaseModel):
    number: Optional[float] = None
    street_name: Optional[str] = None
    street_type: Optional[StreetType] = None
```

---

## 📋 Return Value Summary

| `output` Parameter | Single Module | Multiple Modules |
|-------------------|---------------|------------------|
| `None` (default)  | `str`         | `GeneratedModules` (dict) |
| `Path` (file)     | `None`        | Error |
| `Path` (directory)| `None`        | `None` |

📌 **Note:** When `output` is a file path and multiple modules would be generated, `generate()` raises a `datamodel_code_generator.Error` exception. Use a directory path instead.

With `generate_server` or `generate_client`, `generate()` returns `None` with an `output` and `GeneratedModules` with
every model and package file without one (see [Generating a Server or Client Package](#generating-a-server-or-client-package)).

---

## 📖 See Also

- [Dynamic Model Generation](dynamic-model-generation.md) - Generate Python classes at runtime
- [CLI Reference](cli-reference/index.md) - Complete CLI options (same parameters as module)
- [Generate from JSON Schema](jsonschema.md) - JSON Schema examples

---

# Dynamic Model Generation

Source: https://datamodel-code-generator.koxudaxi.dev/dynamic-model-generation/

Generate real Python model classes from JSON Schema or OpenAPI at runtime without writing files.

## Overview

While `generate()` produces source code as strings, `generate_dynamic_models()` creates actual Python classes that you can use immediately for validation and data processing. This is useful for:

- Runtime schema validation without code generation step
- Dynamic API clients that adapt to schema changes
- Testing and prototyping
- Plugin systems with dynamic schemas

## Quick Start

```python
from datamodel_code_generator import GenerateConfig, generate_dynamic_models

schema = {
    "type": "object",
    "properties": {"name": {"type": "string"}, "age": {"type": "integer"}},
    "required": ["name"],
}

models = generate_dynamic_models(
    schema,
    config=GenerateConfig(class_name="User"),
    target_model_names=["User"],
)
User = models["User"]

# Use the model for validation
user = User(name="Alice", age=30)
print(user.model_dump())  # {'name': 'Alice', 'age': 30}

# Validation errors are raised
try:
    User(age="not a number")  # Missing required 'name', wrong type for 'age'
except Exception as e:
    print(e)
```

## API Reference

### `generate_dynamic_models()`

```python
def generate_dynamic_models(
    input_: Mapping[str, Any],
    *,
    config: GenerateConfig | None = None,
    cache_size: int = 128,
    module_name: str | None = None,
    target_model_names: Sequence[str] | None = None,
) -> dict[str, type]:
```

**Parameters:**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `input_` | `Mapping[str, Any]` | required | JSON Schema or OpenAPI schema as dict |
| `config` | `GenerateConfig \| None` | `None` | Generation options (same as `generate()`) |
| `cache_size` | `int` | `128` | Maximum cached schemas. Set to `0` to disable |
| `module_name` | `str \| None` | `None` | Optional module/package name to assign to generated classes |
| `target_model_names` | `Sequence[str] \| None` | `None` | Optional model names to include in the returned dictionary. Generation still produces all referenced models internally |

**Returns:** `dict[str, type]` - Dictionary mapping class names to model classes.

### `clear_dynamic_models_cache()`

```python
def clear_dynamic_models_cache() -> int:
```

Clears the internal cache and returns the number of entries cleared.

## Examples

### JSON Schema with Nested Models

```python
from datamodel_code_generator import generate_dynamic_models

schema = {
    "$defs": {
        "Address": {
            "type": "object",
            "properties": {"street": {"type": "string"}, "city": {"type": "string"}},
            "required": ["street", "city"],
        },
        "Person": {
            "type": "object",
            "properties": {"name": {"type": "string"}, "address": {"$ref": "#/$defs/Address"}},
            "required": ["name"],
        },
    },
    "$ref": "#/$defs/Person",
}

models = generate_dynamic_models(schema)

# Both models are available
Person = models["Person"]
Address = models["Address"]

person = Person(name="Bob", address={"street": "123 Main St", "city": "NYC"})
print(person.model_dump())
# {'name': 'Bob', 'address': {'street': '123 Main St', 'city': 'NYC'}}
```

### OpenAPI Schema

OpenAPI schemas are auto-detected:

```python
from datamodel_code_generator import generate_dynamic_models

openapi_schema = {
    "openapi": "3.0.0",
    "info": {"title": "User API", "version": "1.0.0"},
    "paths": {},
    "components": {
        "schemas": {
            "User": {
                "type": "object",
                "properties": {"id": {"type": "integer"}, "email": {"type": "string", "format": "email"}},
                "required": ["id", "email"],
            }
        }
    },
}

models = generate_dynamic_models(openapi_schema)
User = models["User"]

user = User(id=1, email="alice@example.com")
```

### With Custom Configuration

```python
from datamodel_code_generator import generate_dynamic_models, GenerateConfig, DataModelType

schema = {"type": "object", "properties": {"name": {"type": "string"}}}

config = GenerateConfig(
    class_name="Customer",
    output_model_type=DataModelType.PydanticV2BaseModel,
)

models = generate_dynamic_models(schema, config=config, target_model_names=["Customer"])
Customer = models["Customer"]
```

### With a Runtime Module Name

```python
from datamodel_code_generator import GenerateConfig, generate_dynamic_models

schema = {"type": "object", "properties": {"name": {"type": "string"}}}

models = generate_dynamic_models(
    schema,
    config=GenerateConfig(class_name="Customer"),
    module_name="runtime_models",
    target_model_names=["Customer"],
)
Customer = models["Customer"]
assert Customer.__module__ == "runtime_models"
```

While the generated code runs, a module of that name is registered in `sys.modules`, unless one already exists, and
removed afterwards, so Pydantic can parameterize generic models such as `RootModel[list[int]]` in it. A module of that
name that can be imported, such as the module of a `base_class` the generated code imports, is imported first and kept
instead.

### Filtering Returned Models

`target_model_names` filters the returned dictionary without pruning generation. Referenced models are still generated
so validation and forward references continue to work.

```python
from datamodel_code_generator import generate_dynamic_models

models = generate_dynamic_models(schema, target_model_names=["User", "Order"])

User = models["User"]
Order = models["Order"]
```

### Enum Models

```python
from datamodel_code_generator import generate_dynamic_models

schema = {"type": "object", "properties": {"status": {"type": "string", "enum": ["pending", "approved", "rejected"]}}}

models = generate_dynamic_models(schema)
Model = models["Model"]
Status = models["Status"]

# Enum validation
item = Model(status="approved")
print(item.status)  # Status.approved
print(item.status.value)  # 'approved'

# Invalid enum value raises error
try:
    Model(status="invalid")
except Exception as e:
    print(e)
```

### Circular References

```python
from datamodel_code_generator import generate_dynamic_models

schema = {
    "$defs": {
        "Node": {
            "type": "object",
            "properties": {
                "value": {"type": "string"},
                "children": {"type": "array", "items": {"$ref": "#/$defs/Node"}},
            },
        }
    },
    "$ref": "#/$defs/Node",
}

models = generate_dynamic_models(schema)
Node = models["Node"]

tree = Node(
    value="root",
    children=[
        Node(value="child1", children=[]),
        Node(value="child2", children=[Node(value="grandchild", children=[])]),
    ],
)
```

## Caching

Models are cached by schema content, configuration, and `module_name` to avoid regeneration.
`target_model_names` only filters the returned dictionary, so it does not change the cache key:

```python
from datamodel_code_generator import generate_dynamic_models, clear_dynamic_models_cache

schema = {"type": "object", "properties": {"x": {"type": "integer"}}}

# First call generates models
models1 = generate_dynamic_models(schema)

# Second call returns cached models (same object)
models2 = generate_dynamic_models(schema)
assert models1 is models2  # True

# Disable caching for specific call
models3 = generate_dynamic_models(schema, cache_size=0)
assert models1 is not models3  # True

# Clear all cached models
cleared = clear_dynamic_models_cache()
print(f"Cleared {cleared} cached schemas")
```

## Thread Safety

`generate_dynamic_models()` is thread-safe. Multiple threads can safely call it concurrently:

```python
import threading
from datamodel_code_generator import generate_dynamic_models

schema = {"type": "object", "properties": {"x": {"type": "integer"}}}
results = []


def worker():
    models = generate_dynamic_models(schema)
    results.append(models)


threads = [threading.Thread(target=worker) for _ in range(10)]
for t in threads:
    t.start()
for t in threads:
    t.join()

# All threads get the same cached models
assert all(r is results[0] for r in results)
```

## Limitations

| Limitation | Details |
|------------|---------|
| Pydantic v2 only | Pydantic v2 is the only supported output |
| Not pickle-able | Use `model_dump()` to serialize instances |
| Dict input only | Schema must be a `dict`, not a file path or string |

## Comparison with `generate()`

| Feature | `generate()` | `generate_dynamic_models()` |
|---------|-------------|----------------------------|
| Output | Source code string | Actual Python classes |
| Use case | Code generation, file output | Runtime validation |
| Caching | No | Yes (configurable) |
| Thread-safe | Yes | Yes |
| Pydantic v2 | Yes | Yes |

## See Also

- [Using as Module](using_as_module.md) - `generate()` function reference
- [JSON Schema](jsonschema.md) - JSON Schema examples
- [OpenAPI](openapi.md) - OpenAPI examples

---

# pyproject.toml Configuration

Source: https://datamodel-code-generator.koxudaxi.dev/pyproject_toml/

<!-- related-cli-options: --all-jobs, --ignore-pyproject, --generate-pyproject-config, --generate-cli-command, --job, --profile, --preset, --watch -->

# ⚙️ pyproject.toml Configuration

datamodel-code-generator can be configured using `pyproject.toml`. The tool automatically searches for `pyproject.toml` in the current directory and parent directories (stopping at the git repository root).

HTTP client selection uses the same values as `--http-backend`. For example,
the experimental HTTPX2 pair can be required explicitly:

```toml
[tool.datamodel-codegen]
http-backend = "httpx2"
```

The default is `"auto"`, which prefers stable HTTPX. See
[HTTP backend selection](faq.md#http-backend-selection).

## 🚀 Basic Usage

```toml
[tool.datamodel-codegen]
input = "schema.yaml"
output = "models.py"
target-python-version = "3.11"
snake-case-field = true
field-constraints = true
```

All CLI options can be used in `pyproject.toml` by converting them to kebab-case (e.g., `--snake-case-field` becomes `snake-case-field`).

On the command line, relative paths in `pyproject.toml` resolve as follows:

- Relative to the `pyproject.toml` directory: `input`, `output`, `custom-template-dir`, `custom-file-header-path`,
  `diff-against`, `emit-model-metadata`, `http-local-ref-path`, `lockfile`, `server-output`, `client-output`, and the
  JSON files of the server and client settings.
- Relative to the working directory: the file of `input-model`, and the JSON files of `aliases`,
  `serialization-aliases`, `extra-template-data`, `custom-formatters-kwargs`, `default-values`, `base-class-map`,
  `model-name-map`, `enum-field-as-literal-map`, `duplicate-name-suffix`, `import-overrides`, `type-overrides`, and
  `validators`.

`load_pyproject_config()` reads those JSON files from the `pyproject.toml` directory instead; see
[Using as Module](using_as_module.md).

## Formatter settings

Formatter selection is configured with the same keys as the CLI:

```toml
[tool.datamodel-codegen]
formatters = ["builtin"]
builtin-format-line-length = 100
```

`builtin-format-line-length` is used only by the built-in formatter. It controls wrapping for `from ... import ...` statements and generated model statements.

If it is not set, the built-in formatter reads existing formatter settings in this order:

1. `[tool.ruff].line-length`
2. `[tool.black].line-length`
3. `[tool.isort].line_length`
4. `88`

See [Formatter Behavior](formatter-behavior.md) for the full built-in formatter scope.

## 📋 Named Profiles

You can define multiple named profiles for different use cases within a single project:

```toml
[tool.datamodel-codegen]
target-python-version = "3.10"

[tool.datamodel-codegen.profiles.strict]
snake-case-field = true
use-annotated = true

[tool.datamodel-codegen.profiles.py311]
target-python-version = "3.11"
```

Base settings in `[tool.datamodel-codegen]` are used when no profile is specified, and also serve as defaults for profiles.

Use a profile with the `--profile` option:

```bash
datamodel-codegen --input schemas/api.yaml --output src/models/api.py --profile strict
datamodel-codegen --input schemas/db.json --output src/models/db.py --profile py311
```

## 🏃 Named Jobs (Experimental)

!!! warning "Experimental"

    Named batch jobs are experimental; their configuration schema, batch output,
    and transactional/watch execution contracts may change.

Profiles are reusable configuration fragments. A job is a runnable generation
that supplies its own `input` and `output` and can select one profile.

```toml
[tool.datamodel-codegen.jobs.api]
profile = "strict"
input = "schemas/api.yaml"
output = "src/models/api.py"

[tool.datamodel-codegen.jobs.database]
profile = "py311"
input = "schemas/db.json"
output = "src/models/db.py"
input-file-type = "jsonschema"
```

Run selected jobs or every job:

```bash
datamodel-codegen --job api
datamodel-codegen --job api --job database --check
datamodel-codegen --all-jobs
```

Jobs always run sequentially in their TOML declaration order. Before generation,
all selected jobs are validated: each must have an input and output, and output
or model-metadata paths cannot overlap, with two exceptions: jobs that each select
`generate-server` or `generate-client` may name the same models `output`, which the
batch writes once and fails on if their generated model files differ, and a job may
keep its models inside its own server or client output, or that output inside its
models directory. `--job` and `--all-jobs` are mutually
exclusive. Define job-specific input and output in TOML instead of combining
job selection with `--input`, `--url`, `--input-model`, `--output`, `--profile`,
`--diff-against`, or job-specific watch settings. Input comparison is a
single-profile/input operation and is rejected if it is inherited by any
selected job. `watch` and `watch-delay` may be set on the CLI or in the base
`[tool.datamodel-codegen]` table, but cannot be set in a job table or in the
selected profile. Batch watch observes the union of every selected job's local
dependencies plus `pyproject.toml`. Each event reloads the project, replans the
selection, and transactionally reruns the whole batch; it does not partially
rebuild individual jobs. A failed cycle keeps the last published outputs and
continues watching both prior and newly discovered dependencies for recovery.

A job whose settings select `generate-server` also generates the FastAPI server
package, and a job whose settings select `generate-client` also generates the Python
client package; such jobs can share one models `output`; see [Batch jobs](fastapi-server.md#batch-jobs).
Server and client generation are experimental; see [FastAPI Server Generation](fastapi-server.md) and
[Python Client Generation](python-client.md).

## 🎯 Configuration Priority

Settings are applied in the following priority order (highest to lowest):

1. **🖥️ CLI arguments** - Always take precedence
2. **🏃 Job settings** - From `[tool.datamodel-codegen.jobs.<name>]`
3. **📋 Profile settings** - From `[tool.datamodel-codegen.profiles.<name>]`
4. **⚙️ Base settings** - From `[tool.datamodel-codegen]`
5. **🔧 Default values** - Built-in defaults

## 🔀 Merge Rules

When using profiles, settings are merged using **shallow merge**:

- Profile values **completely replace** base values (no deep merging)
- Settings not specified in the profile are inherited from the base configuration
- Lists and dictionaries are replaced entirely, not merged

### 📝 Example

```toml
[tool.datamodel-codegen]
strict-types = ["str", "int"]
http-headers = ["Authorization: Bearer token"]

[tool.datamodel-codegen.profiles.api]
strict-types = ["bytes"]
```

When using `--profile api`:

- `strict-types` becomes `["bytes"]` (completely replaces base, not merged)
- `http-headers` is inherited from base as `["Authorization: Bearer token"]`

## 🚫 Ignoring pyproject.toml

To ignore all `pyproject.toml` configuration and use only CLI arguments:

```bash
datamodel-codegen --ignore-pyproject --input schema.yaml --output models.py
```

## 🔧 Generating Configuration

Generate a `pyproject.toml` configuration section from CLI arguments:

```bash
datamodel-codegen --input schema.yaml --output models.py --snake-case-field --generate-pyproject-config
```

**✨ Output:**

```toml
[tool.datamodel-codegen]
input = "schema.yaml"
output = "models.py"
snake-case-field = true
```

Generate CLI command from existing `pyproject.toml`:

```bash
datamodel-codegen --generate-cli-command
```

With a specific profile:

```bash
datamodel-codegen --profile api --generate-cli-command
```

---

## 📖 See Also

- 🧰 [Presets](presets.md) - Recommended immutable option bundles for modern output
- 🖥️ [CLI Reference: `--ignore-pyproject`](cli-reference/general-options.md#ignore-pyproject) - Ignore pyproject.toml configuration
- 🔧 [CLI Reference: `--generate-pyproject-config`](cli-reference/general-options.md#generate-pyproject-config) - Generate pyproject.toml from CLI arguments
- 🖥️ [CLI Reference: `--generate-cli-command`](cli-reference/general-options.md#generate-cli-command) - Generate CLI command from pyproject.toml

---

# CI/CD Integration

Source: https://datamodel-code-generator.koxudaxi.dev/ci-cd/

<!-- related-cli-options: --check, --disable-timestamp, --formatters, --target-python-version, --profile -->

# CI/CD Integration

This guide covers how to use datamodel-code-generator in CI/CD pipelines and development workflows to ensure generated code stays in sync with schemas.

!!! note
    The package name is `datamodel-code-generator`, and the CLI command is `datamodel-codegen`.

---

## Official GitHub Action

The official GitHub Action provides a simple way to validate generated models in your CI pipeline.

### Basic Usage

```yaml
- uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
  with:
    input: schema.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
```

Replace `vX.Y.Z` with the release tag you want to pin.

By default, the action runs in **check mode** (`--check`), which validates that the existing output file matches what would be generated. If they differ, the action fails.

### Inputs

| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| `input` | Yes | - | Input schema file or directory |
| `output` | Yes | - | Output file or directory |
| `input-file-type` | Yes | - | Input file type (`openapi`, `asyncapi`, `jsonschema`, `mcp-tools`, `xmlschema`, `graphql`, `protobuf`, `avro`, `json`, `yaml`, `csv`) |
| `output-model-type` | Yes | - | Output model type (`pydantic_v2.BaseModel`, `pydantic_v2.dataclass`, `dataclasses.dataclass`, `typing.TypedDict`, `msgspec.Struct`) |
| `check` | No | `true` | Validate that existing output is up to date (no generation) |
| `working-directory` | No | `.` | Working directory (where `pyproject.toml` is located) |
| `profile` | No | - | Named profile from `pyproject.toml` |
| `extra-args` | No | - | Additional CLI arguments |
| `version` | No | - | Specific version to install (defaults to action's tag version) |
| `extras` | No | - | Optional extras to install (comma-separated: `graphql`, `http`, `validation`, `ruff`, `all`) |

### Example: Validate on Pull Request

```yaml title=".github/workflows/validate-models.yml"
name: Validate Generated Models

on:
  pull_request:
    paths:
      - 'schemas/**'
      - 'src/models/**'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
        with:
          input: schemas/api.yaml
          output: src/models/api.py
          input-file-type: openapi
          output-model-type: pydantic_v2.BaseModel
```

### Example: Monorepo with Multiple Schemas

```yaml title=".github/workflows/validate-models.yml"
jobs:
  validate:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - working-directory: packages/api
            input: schemas/openapi.yaml
            output: src/models.py
            input-file-type: openapi
          - working-directory: packages/admin
            input: schemas/schema.json
            output: src/models.py
            input-file-type: jsonschema
    steps:
      - uses: actions/checkout@v4

      - uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
        with:
          input: ${{ matrix.input }}
          output: ${{ matrix.output }}
          input-file-type: ${{ matrix.input-file-type }}
          output-model-type: pydantic_v2.BaseModel
          working-directory: ${{ matrix.working-directory }}
```

### Example: Using Profiles

```yaml
- uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
  with:
    input: schemas/api.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
    profile: api
```

### Example: Generate Models (Instead of Validation)

Set `check: 'false'` to actually generate the models:

```yaml
- uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
  with:
    input: schema.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
    check: 'false'
```

### Example: GraphQL Schema

For GraphQL schemas, use the `extras` input to install the required dependency:

```yaml
- uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
  with:
    input: schema.graphql
    output: src/models.py
    input-file-type: graphql
    output-model-type: pydantic_v2.BaseModel
    extras: 'graphql'
```

### Example: Apache Avro Schema

```yaml
- uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
  with:
    input: schema.avsc
    output: src/models.py
    input-file-type: avro
    output-model-type: pydantic_v2.BaseModel
```

### Example: Multiple Extras

You can install multiple extras with comma-separated values:

```yaml
- uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
  with:
    input: schema.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
    extras: 'http,validation,ruff'
```

### Example: Additional CLI Options

Use `extra-args` for CLI options not covered by the inputs:

```yaml
- uses: datamodel-code-generator/datamodel-code-generator@vX.Y.Z
  with:
    input: schema.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
    extra-args: '--snake-case-field --field-constraints'
```

!!! tip "Version Pinning"
    Always pin the action to a specific version tag (e.g., `@vX.Y.Z`) to ensure reproducible builds. The action installs the same version of `datamodel-code-generator` as the tag.

---

## The `--check` Flag

The `--check` flag verifies that generated code matches existing files without modifying them. If the output would differ, it exits with a non-zero status code.

```bash
datamodel-codegen --check
```

### Success (Exit code 0)

When generated code matches the existing file, the command exits silently with code 0:

```console
$ datamodel-codegen --check
$ echo $?
0
```

### Failure (Exit code 1)

When the schema has changed and the generated code would differ, a unified diff is shown and the command exits with code 1:

```console
$ datamodel-codegen --check
--- models.py
+++ models.py (expected)
@@ -12,3 +12,4 @@
     name: Optional[str] = None
     age: Optional[int] = None
     email: Optional[str] = None
+    active: Optional[bool] = None
$ echo $?
1
```

!!! tip "Best Practice: Use pyproject.toml"
    Instead of passing many CLI options, configure all settings in `pyproject.toml`. This keeps CI commands simple, ensures consistency between local development and CI, and makes configuration easier to maintain.

    ```toml title="pyproject.toml"
    [tool.datamodel-codegen]
    input = "schemas/api.yaml"
    output = "src/models/api.py"
    output-model-type = "pydantic_v2.BaseModel"
    disable-timestamp = true
    ```

    Then simply run:

    ```bash
    datamodel-codegen --check
    ```

    For projects with multiple schemas, use [named profiles](pyproject_toml.md#named-profiles) to organize configurations by purpose.

**Related:** [`--check`](cli-reference/general-options.md#check), [`--disable-timestamp`](cli-reference/template-customization.md#disable-timestamp), [pyproject.toml Configuration](pyproject_toml.md)

---

## GitHub Actions

### Basic Example

```yaml title=".github/workflows/ci.yml"
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  check-generated-code:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.14"

      - name: Install dependencies
        run: pip install datamodel-code-generator

      - name: Verify generated models are up-to-date
        run: datamodel-codegen --check
```

### Using Profiles for Multiple Schemas

For projects with multiple schemas, use [named profiles](pyproject_toml.md#named-profiles) to organize configurations by purpose:

```toml title="pyproject.toml"
[tool.datamodel-codegen]
output-model-type = "pydantic_v2.BaseModel"
disable-timestamp = true

[tool.datamodel-codegen.profiles.api]
input = "schemas/openapi/api.yaml"
output = "src/models/api.py"

[tool.datamodel-codegen.profiles.events]
input = "schemas/jsonschema/events.json"
output = "src/models/events.py"
input-file-type = "jsonschema"
```

```yaml title=".github/workflows/ci.yml"
- name: Verify API models are up-to-date
  run: datamodel-codegen --profile api --check

- name: Verify event models are up-to-date
  run: datamodel-codegen --profile events --check
```

### Using uv

If your project uses [uv](https://github.com/astral-sh/uv), you can run the CLI via `uv run`. This example installs the tool ephemerally (no need to add it to your project dependencies):

```yaml title=".github/workflows/ci.yml"
- name: Install uv
  uses: astral-sh/setup-uv@v4

- name: Verify generated models are up-to-date
  run: uv run --with datamodel-code-generator datamodel-codegen --profile api --check
```

If you want the generator version pinned in your project lockfile, add it once with `uv add --dev datamodel-code-generator`
and run `uv run datamodel-codegen --profile api --check` in CI.

---

## Pre-commit Hook

You can use datamodel-code-generator as a [pre-commit](https://pre-commit.com/) hook to automatically check or regenerate models before commits.

!!! tip
    Pin `rev` to a released tag (e.g., `vX.Y.Z`) to keep generated output stable and reproducible across developer machines and CI.

### With pyproject.toml (Recommended)

Configure settings in `pyproject.toml` and use a simple pre-commit hook:

```yaml title=".pre-commit-config.yaml"
repos:
  - repo: https://github.com/datamodel-code-generator/datamodel-code-generator
    rev: vX.Y.Z
    hooks:
      - id: datamodel-code-generator
        args: [--check]
        files: ^schemas/
```

### With Profiles

For projects with multiple schemas using [named profiles](pyproject_toml.md#named-profiles):

```yaml title=".pre-commit-config.yaml"
repos:
  - repo: https://github.com/datamodel-code-generator/datamodel-code-generator
    rev: vX.Y.Z
    hooks:
      - id: datamodel-code-generator
        name: Check API models
        args: [--profile, api, --check]
        files: ^schemas/openapi/
      - id: datamodel-code-generator
        name: Check event models
        args: [--profile, events, --check]
        files: ^schemas/jsonschema/
```

### Auto-regenerate Mode

This configuration automatically regenerates models when schema files change:

```yaml title=".pre-commit-config.yaml"
repos:
  - repo: https://github.com/datamodel-code-generator/datamodel-code-generator
    rev: vX.Y.Z
    hooks:
      - id: datamodel-code-generator
        files: ^schemas/
```

!!! note "Installing the hook"
    Ensure `pre-commit` is installed, then install the hooks:

    ```bash
    pip install pre-commit
    pre-commit install
    ```

---

## GitLab CI

```yaml title=".gitlab-ci.yml"
check-generated-code:
  image: python:3.14
  script:
    - pip install datamodel-code-generator
    - datamodel-codegen --check
  rules:
    - changes:
        - schemas/**/*
        - src/models/**/*
```

---

## Makefile Integration

Add targets to your Makefile for easy generation and checking:

```makefile title="Makefile"
.PHONY: generate-models check-models

generate-models:
	datamodel-codegen

check-models:
	datamodel-codegen --check
```

Then use in CI:

```yaml title=".github/workflows/ci.yml"
- name: Check generated models
  run: make check-models
```

For projects with multiple profiles:

```makefile title="Makefile"
.PHONY: generate-all check-all

generate-all:
	datamodel-codegen --profile api
	datamodel-codegen --profile events

check-all:
	datamodel-codegen --profile api --check
	datamodel-codegen --profile events --check
```

---

## Troubleshooting

### Check fails due to formatting differences

Ensure you're using the same formatters in CI as locally. Configure formatters in `pyproject.toml`:

```toml title="pyproject.toml"
[tool.datamodel-codegen]
formatters = ["ruff"]
```

See [Formatting](formatting.md) for details.

**Related:** [`--formatters`](cli-reference/template-customization.md#formatters)

### Check fails due to timestamp

Always use `disable-timestamp = true` in `pyproject.toml`:

```toml title="pyproject.toml"
[tool.datamodel-codegen]
disable-timestamp = true
```

**Related:** [`--disable-timestamp`](cli-reference/template-customization.md#disable-timestamp)

### Different Python versions produce different output

Some type annotations differ between Python versions. Pin the target version in `pyproject.toml` and ensure CI uses the same Python version as development:

```toml title="pyproject.toml"
[tool.datamodel-codegen]
target-python-version = "3.14"
```

**Related:** [`--target-python-version`](cli-reference/model-customization.md#target-python-version)

---

# LLM Integration

Source: https://datamodel-code-generator.koxudaxi.dev/llm-integration/

<!-- related-cli-options: --generate-prompt, --output-format, --output-format-json-schema -->

The `--generate-prompt` option generates a formatted prompt that you can use
to consult Large Language Models (LLMs) about datamodel-code-generator CLI options.

## Overview

When you're unsure which CLI options to use for your specific use case,
generate a prompt that includes the options already selected for the command,
the available options grouped by category, and the full help text. Give that
prompt to an LLM and ask it to propose the smallest command that satisfies your
schema and generation goal.

```bash
datamodel-codegen --generate-prompt "How do I generate strict Pydantic v2 models?"
```

The generated prompt includes:

- Your question (if provided)
- Current CLI options you've specified
- All options organized by category with descriptions
- Full help text for reference

## If You Are an LLM Agent

Use `--generate-prompt` as an option discovery step before you recommend or run
a final `datamodel-codegen` command.

1. Inspect the user's goal and the input schema when it is available.
2. Start from any options the user or existing project already selected.
3. Run `datamodel-codegen [known options] --generate-prompt "<goal>"`.
4. Preserve current options unless they conflict with the goal or another option.
5. Choose the minimal additional options needed for the requested output.
6. Return the final CLI command, reasons for each non-obvious option, rejected
   alternatives, and a verification command.

Use current options in the prompt command so the generated prompt reflects the
real configuration you are improving:

```bash
datamodel-codegen \
    --input openapi.yaml \
    --input-file-type openapi \
    --output models.py \
    --output-model-type pydantic_v2.BaseModel \
    --target-python-version 3.12 \
    --generate-prompt "Find the minimal options for strict API response models."
```

A useful answer should keep the command runnable and explain tradeoffs:

- Final command to run
- Why each added or changed option is needed
- Current options that should remain unchanged
- Options considered but rejected, with a short reason
- Verification command, such as `datamodel-codegen ... --check` or a focused
  generation command against a fixture schema

## Structured Output for Tools

Use `--output-format json` when an LLM agent or tool should consume structured option
metadata instead of Markdown:

```bash
datamodel-codegen --generate-prompt "How do I generate strict Pydantic v2 models?" --output-format json
```

The JSON payload includes the user question, current options, options grouped by
category, full option metadata from argparse, and help text without ANSI color
codes.

Use `--output-format-json-schema` when a tool or agent needs a JSON Schema before
it consumes command output:

```bash
datamodel-codegen --output-format-json-schema config
datamodel-codegen --output-format-json-schema generate-prompt
datamodel-codegen --output-format-json-schema generation
datamodel-codegen --output-format-json-schema structured-output
```

The schema targets are scoped:

- `config`: schema for JSON configuration options such as `--aliases`,
  `--type-overrides`, and `--validators`
- `generate-prompt`: schema for `--generate-prompt --output-format json`
- `generation`: schema for normal generation with `--output-format json`
- `structured-output`: tagged union schema for all structured command outputs,
  including prompt, generation, command metadata, and check result payloads

## CLI LLM Tools

Pipe the generated prompt directly to CLI-based LLM tools:

### Claude Code

[Claude Code](https://docs.anthropic.com/en/docs/claude-code) is Anthropic's official CLI tool.
Use `-p` flag for non-interactive (pipe) mode:

```bash
datamodel-codegen --generate-prompt "Best options for API response models?" | claude -p
```

### OpenAI Codex CLI

[Codex CLI](https://github.com/openai/codex) is OpenAI's CLI tool.
Use `exec` subcommand for non-interactive mode:

```bash
datamodel-codegen --generate-prompt "How to handle nullable fields?" | codex exec
```

For agents that can inspect structured input, prefer JSON:

```bash
datamodel-codegen --generate-prompt "How to handle nullable fields?" --output-format json | codex exec
```

### Other CLI Tools

Other popular LLM CLI tools that accept stdin:

| Tool | Command | Repository |
|------|---------|------------|
| llm | `\| llm` | [simonw/llm](https://github.com/simonw/llm) |
| aichat | `\| aichat` | [sigoden/aichat](https://github.com/sigoden/aichat) |
| sgpt | `\| sgpt` | [TheR1D/shell_gpt](https://github.com/TheR1D/shell_gpt) |
| mods | `\| mods` | [charmbracelet/mods](https://github.com/charmbracelet/mods) |

Check each tool's documentation for specific usage and options.

## Web LLM Chat Services

Copy the prompt to clipboard, then paste into your preferred web-based LLM chat:

### macOS

```bash
datamodel-codegen --generate-prompt | pbcopy
```

### Linux (X11)

```bash
datamodel-codegen --generate-prompt | xclip -selection clipboard
```

### Linux (Wayland)

```bash
datamodel-codegen --generate-prompt | wl-copy
```

### Windows (PowerShell)

```powershell
datamodel-codegen --generate-prompt | Set-Clipboard
```

### WSL2

```bash
datamodel-codegen --generate-prompt | clip.exe
```

## Usage Examples

### Basic Usage

Generate a prompt without a specific question:

```bash
datamodel-codegen --generate-prompt
```

### JSON Output

Generate structured option metadata for automated tools:

```bash
datamodel-codegen --generate-prompt "Find the minimal strict-model options." --output-format json
```

### With a Question

Include your specific question in the prompt:

```bash
datamodel-codegen --generate-prompt "What options should I use for GraphQL schema?"
```

### With Current Options

Show your current configuration and ask for improvements:

```bash
datamodel-codegen \
    --input schema.json \
    --output-model-type pydantic_v2.BaseModel \
    --use-annotated \
    --generate-prompt "Are there any other options I should consider?"
```

### Strict Pydantic v2 Models

```bash
datamodel-codegen \
    --input openapi.yaml \
    --input-file-type openapi \
    --output models.py \
    --output-model-type pydantic_v2.BaseModel \
    --target-python-version 3.12 \
    --strict-types str int float bool \
    --generate-prompt "Which additional options should I use for strict API response models?" \
    | claude -p
```

### Review an Existing Command

```bash
datamodel-codegen \
    --input schema.json \
    --output models.py \
    --output-model-type pydantic_v2.BaseModel \
    --target-python-version 3.11 \
    --snake-case-field \
    --generate-prompt "Review this command and suggest only necessary option changes." \
    | codex exec
```

## Tips

1. **Be specific** - Include a clear question to get more relevant recommendations
2. **Show context** - Add your current options so the LLM understands your setup
3. **Keep options minimal** - Prefer the fewest options that satisfy the goal
4. **Verify output** - Run the final command against the target schema or fixture

---

# Using datamodel-code-generator with coding agents

Source: https://datamodel-code-generator.koxudaxi.dev/coding-agent-skill/

This repository includes an experimental Agent Skill for skills-compatible coding agents. The skill teaches an agent to run `datamodel-codegen` when a user asks for Python models from OpenAPI, AsyncAPI, JSON Schema, GraphQL, JSON/YAML/CSV sample data, MCP tool schemas, Protocol Buffers, XML Schema, Apache Avro, or existing Python model objects.

The skill is a directory with a `SKILL.md` entrypoint and supporting files under
`references/`. It is bundled with the CLI and can be installed without checking
out this repository.

Treat this skill as experimental. The workflow, trigger wording, and client-specific install guidance can change as Codex, Claude Code, and other skills-compatible agents evolve.

## Why agents should run the CLI

Agents should run `datamodel-codegen` instead of hand-writing generated models when a usable input artifact exists.

The CLI handles refs, enums, nested models, unions, `allOf`, `oneOf`, `anyOf`, and model reuse. It also produces output that can be imported and checked after generation.

Agents should also use the CLI for option discovery. `datamodel-codegen --help` links to this skill documentation, and `--generate-prompt` can produce either Markdown guidance or structured JSON for tool-aware agents.

```bash
datamodel-codegen [known options] --generate-prompt "Find the minimal options for this schema."
datamodel-codegen [known options] --generate-prompt "Find the minimal options for this schema." --output-format json
datamodel-codegen --output-format-json-schema structured-output
```

Use the generated prompt output before recommending a final command when the correct input type, output model type, strictness, aliasing, module layout, or verification flags are not obvious.

## Install for Claude Code

Claude Code project skills load from `.claude/skills/` in the starting directory and parent directories up to the repository root. Personal skills can be placed under `~/.claude/skills/`.

For a project skill, run:

```bash
datamodel-codegen --install-skill claude-code
```

For a personal skill, run:

```bash
datamodel-codegen --install-skill claude-code --skill-scope user
```

Claude Code can invoke a skill directly with `/datamodel-code-generator`, or load it automatically when the description matches the task. Existing top-level skill directories are watched for changes. If the top-level skills directory did not exist when the session started, restart Claude Code.

## Install for Codex

Codex reads project skills from `.agents/skills` in the current directory, parent directories, and the repository root. It reads personal skills from `$HOME/.agents/skills`.

For a project skill, run:

```bash
datamodel-codegen --install-skill codex
```

For a personal skill, run:

```bash
datamodel-codegen --install-skill codex --skill-scope user
```

Codex can invoke skills explicitly through `/skills` or `$` mention, or load them automatically when the description matches the task.

The installer preserves an existing skill directory by default. Use
`--overwrite-skill` only when you want to replace it; symlinks and
non-directory targets are never overwritten.

## Other agents

Other skills-compatible agents may support this directory format. Check the client documentation for its skill search path.

## Distribution paths

| Form | Install method | Best use |
| --- | --- | --- |
| Repository skill | Copy to `.agents/skills/` or `.claude/skills/` | OSS and internal repositories |
| Personal skill | Copy to `~/.agents/skills/` or `~/.claude/skills/` | Reuse across a user's projects |
| Codex local install | Use `$skill-installer` when appropriate | Codex local experiments |
| Codex plugin | Package separately as a plugin | Reusable Codex distribution |
| Claude plugin | Package separately as a plugin | Bundle skills with hooks, MCP, or agents |

Start with the repository skill. Consider Codex or Claude plugin packaging only as a separate distribution task.

## Example prompt

```text
Create Pydantic v2 models from openapi.yaml.
```

Expected agent behavior:

1. Runs `datamodel-codegen`.
2. Writes the generated file.
3. Imports the generated file.
4. Summarizes generated classes.

## Troubleshooting

- The CLI command is `datamodel-codegen`.
- The package name is `datamodel-code-generator`.
- Use extras for HTTP, GraphQL, and protobuf when needed. Install `msgspec` separately when targeting `msgspec.Struct`.
- If a JSON or YAML file is a schema, choose `openapi`, `asyncapi`, or `jsonschema` input type instead of raw sample data mode.

## References

- [Agent Skills specification](https://agentskills.io/specification)
- [Codex Agent Skills](https://developers.openai.com/codex/skills)
- [Claude Code skills](https://docs.anthropic.com/en/docs/claude-code/skills)

---

# FastAPI Server Generation

Source: https://datamodel-code-generator.koxudaxi.dev/fastapi-server/

!!! warning "Experimental"

    FastAPI server generation is experimental. Its options, generated package, template values, and served
    OpenAPI document may change. See [Experimental Features](experimental.md).

`--generate-server fastapi` turns one OpenAPI document into the models and a FastAPI server package in the same run.
The package holds everything the document decides: the routes, a service Protocol that lists the operations you
implement, the code that reads requests and writes responses, authentication, and the OpenAPI document the server
publishes.

You write only the business logic, in the `services` modules beside the package, which the generator writes once with
stubs and never overwrites. Type checkers and Python check that your code implements every operation, so when the
document changes, you regenerate the package and fix what they report.

```text
openapi.yaml ──► datamodel-codegen ──► app/models.py, app/server/    generated, overwritten on every run
                         │                  ▲  app/server/main.py imports app/services/
                         │ once, with stubs │ import, subclass the service Protocols
                         └─────────────► app/services/               yours, never overwritten
```

Coming from fastapi-code-generator? See [Migrating from fastapi-code-generator](fastapi-code-generator-migration.md).

This page covers a tutorial, how-tos for implementing the services, and the reference of the generated package. For
the client of the same document, see [Python Client Generation](python-client.md); for every option with examples,
see [CLI Reference: Target Generation Options](cli-reference/target-generation-options.md).

## Quick start

This tutorial builds a small pet store that lists, creates, and finds pets. Start in an empty directory of a uv
project, with `datamodel-codegen` [installed](getting-started.md#installation). Server generation needs Python 3.11 or
later; the preset below targets Python 3.12.

### 1. Describe the API

Save the document as `openapi.yaml`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.openapi -->
<details>
<summary>openapi.yaml</summary>

<!-- fmt: off -->

```yaml
openapi: 3.1.0
info:
  title: Pets
  version: "1.0"
servers:
  - url: http://localhost:8000
paths:
  /pets:
    get:
      operationId: listPets
      tags: [pets]
      parameters:
        - name: limit
          in: query
          schema: {type: integer, minimum: 1, maximum: 100, default: 20}
      responses:
        "200":
          description: The pets.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pets"}
    post:
      operationId: createPet
      tags: [pets]
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: "#/components/schemas/NewPet"}
      responses:
        "201":
          description: Created.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
  /pets/{petId}:
    get:
      operationId: getPet
      tags: [pets]
      parameters:
        - name: petId
          in: path
          required: true
          schema: {type: integer}
      responses:
        "200":
          description: The pet.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
        "404":
          description: No pet has this ID.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Error"}
components:
  schemas:
    NewPet:
      type: object
      required: [name]
      properties:
        name: {type: string}
        tag: {type: string}
    Pet:
      type: object
      required: [id, name]
      properties:
        id: {type: integer}
        name: {type: string}
        tag: {type: string}
    Pets:
      type: array
      items: {$ref: "#/components/schemas/Pet"}
    Error:
      type: object
      required: [message]
      properties:
        message: {type: string}
```

<!-- fmt: on -->
</details>
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.openapi -->

Each operation has an `operationId`, which names the Python method that implements it, and a tag. Operations that
share their first tag form a *router group*: here the three `pets` operations, which the server registers on one
FastAPI router.

The bodies and responses refer to schemas under `components`, so their models take the names you chose, such as
`Pet` and `NewPet`.

### 2. Generate the server

Everything goes into one application package, `app`. Create it with an empty `app/__init__.py`, which makes `app` a
package; keeping the generated packages inside your application package, instead of as top-level packages such as
`models` or `server`, avoids generic top-level names that collide easily with other projects and libraries, and shows
at a glance what is generated and what is yours:

```bash
mkdir -p app && touch app/__init__.py
```

Put the settings in `pyproject.toml` and run `datamodel-codegen` without arguments, or pass them as options:

=== "pyproject.toml"

    <!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.pyproject -->
    <!-- fmt: off -->

    ```toml
    [tool.datamodel-codegen]
    input = "openapi.yaml"
    input-file-type = "openapi"
    openapi-scopes = ["schemas", "api"]
    output-model-type = "pydantic_v2.BaseModel"
    preset = "standard-py312-20261015"
    output = "app/models.py"
    generate-server = "fastapi"
    server-output = "app/server"
    server-package = "app.server"
    server-model-package = "app.models"
    ```

    <!-- fmt: on -->

    <!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.pyproject -->

=== "Command line"

    <!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.command -->
    <!-- fmt: off -->

    ```bash
    datamodel-codegen \
      --input openapi.yaml \
      --input-file-type openapi \
      --openapi-scopes schemas api \
      --output-model-type pydantic_v2.BaseModel \
      --preset standard-py312-20261015 \
      --output app/models.py \
      --generate-server fastapi \
      --server-output app/server \
      --server-package app.server \
      --server-model-package app.models
    ```

    <!-- fmt: on -->

    <!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.command -->

The [preset](presets.md) supplies the model options, as in the model [quick start](getting-started.md), and
`--openapi-scopes schemas api` makes models for the parameters, bodies, and responses of the operations too.

Generation ends by printing the command that adds the package's runtime dependencies to your project, and the
next steps:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.notice -->
<!-- fmt: off -->

```text
Add the runtime dependencies of app.server to your project:
  uv add "fastapi>=0.141.1" "pydantic>=2.14.0" "typing-extensions>=4.16"
Next steps: implement the stubs in app/services/pets.py, then run the server:
  uv add uvicorn && uv run uvicorn app.server.main:app --reload
or: uv add "fastapi[standard]" && uv run fastapi dev --entrypoint app.server.main:app
See app/server/README.md.
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.notice -->

Run the `uv add` command. It names only the minimum version of each package, so uv adds the latest release, and
it grows with what the document uses: `python-multipart` for forms, `email-validator` for `format: email`, and
`python-ulid` for `format: ulid`. An explicit `--target-pydantic-version` older than the `pydantic` minimum (`2`, `2.11` or `2.12`) is
refused with `Error:` and exit code 2; leave it unset or use `2.14`, which `--use-missing-sentinel` requires (see
[Requirements](#requirements)).

The run wrote the models, the `app.server` package, and, once, the `app.services` package with a stub for you to
implement:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.tree -->
<!-- fmt: off -->

```text
app/
├── __init__.py
├── models.py
├── server/
│   ├── README.md
│   ├── __init__.py
│   ├── _generated/
│   ├── _runtime/
│   ├── application.py
│   ├── main.py
│   ├── py.typed
│   ├── routers/
│   │   ├── __init__.py
│   │   └── pets.py
│   └── services.py
└── services/
    ├── __init__.py
    └── pets.py
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.tree -->

`app/models.py` holds the models, `app/server/services.py` the service Protocol you implement next,
`app/server/routers/` the routes, and `app/server/main.py` the application. The rest is described in
[The generated package](#the-generated-package). Every file of `app/models.py` and `app/server/` is overwritten on each
run, so keep your own code outside `app/server/`: generation writes `app/services/pets.py` only while it is missing,
and never overwrites or deletes it.

### 3. Read the service Protocol

`app/server/services.py` declares one *service Protocol* for each router group: a `typing.Protocol` class with an
abstract method for each operation.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.services -->
<!-- fmt: off -->

```python
"""Service interfaces of this package's router groups; regenerate them instead of editing."""

from __future__ import annotations

from abc import abstractmethod
from typing import Protocol

from app import models
from fastapi.responses import Response

from ._runtime.server.responses import HTTPResult


class PetsService(Protocol):
    """Implement the pets operations: subclass this Protocol, or give an object its methods."""

    @abstractmethod
    def list_pets(
        self,
        *,
        limit: int,
    ) -> models.Pets | HTTPResult[models.Pets] | Response:
        """
        Handle GET /pets.
        """

    @abstractmethod
    def create_pet(
        self,
        *,
        body: models.NewPet,
    ) -> models.Pet | HTTPResult[models.Pet] | Response:
        """
        Handle POST /pets.
        """

    @abstractmethod
    def get_pet(
        self,
        *,
        pet_id: int,
    ) -> models.Pet | HTTPResult[models.Pet | models.Error] | Response:
        """
        Handle GET /pets/{petId}.
        """
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.services -->

Each method takes the operation's parameters and body as keyword arguments, already validated by the models.
`limit` arrives as `20` when the request omits it, the default its schema declares, and the `petId` path parameter
arrives as `pet_id`, since the preset turns on snake-case field names.

A method returns one of three things:

- the model of its *primary response*, the response a bare return value takes: `200` when the operation declares
  it, or else its lowest success status, such as `201` for `create_pet`, or else its `2XX` or `default` response
  (see [Responses](#responses) for the full rule);
- an `HTTPResult` for another status or extra headers, such as the `404` that `get_pet` declares;
- a Starlette `Response`, sent as it is.

### 4. Implement the operations

Generation wrote `app/services/pets.py` with a class `Pets` that subclasses `PetsService` and a stub for each method,
which raises `NotImplementedError`. Replace the stubs with the business logic:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.app -->
<!-- fmt: off -->

```python
from app import models
from app.server import HTTPResult
from app.server.services import PetsService


class Pets(PetsService):
    def __init__(self) -> None:
        self.pets: dict[int, models.Pet] = {}

    def list_pets(self, *, limit: int) -> models.Pets:
        return models.Pets(list(self.pets.values())[:limit])

    def create_pet(self, *, body: models.NewPet) -> models.Pet:
        pet = models.Pet(id=len(self.pets) + 1, name=body.name, tag=body.tag)
        self.pets[pet.id] = pet
        return pet

    def get_pet(self, *, pet_id: int) -> models.Pet | HTTPResult[models.Error]:
        if (pet := self.pets.get(pet_id)) is None:
            return HTTPResult(404, models.Error(message=f"Pet {pet_id} not found"))
        return pet
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.app -->

`Pets` subclasses `PetsService`, so type checkers report a missing method or one whose arguments or result do not
match its operation, and Python refuses to create `Pets()` while a method is missing.
`HTTPResult(404, models.Error(...))` sends the `404` response that `get_pet` declares, validated by its `Error` model.

Each router group has its module in `app/services`, named after the group's router module, with a class named after its
Protocol without the `Service` suffix; a document with security schemes adds `app/services/authorize.py` with the
`authorize` function. The package README lists them under *Next steps*. `app/server/main.py` imports them and calls
`create_app`, which takes one service for each router group, under the group's name, and returns a FastAPI
application. In short, it does this:

```python
from app.server import create_app
from app.services.pets import Pets

app = create_app(pets=Pets())
```

### 5. Run it

```bash
uv add uvicorn
uv run uvicorn app.server.main:app --reload
```

Run it from the directory that holds the top-level package, `app`; for a `src` layout, add `--app-dir src`, which the
next steps printed after generation add for you. FastAPI's own command runs it too, after
`uv add "fastapi[standard]"`. For a nested package such as `app.server`, it takes the import string:
`uv run fastapi dev --entrypoint app.server.main:app`, which the next steps printed too, with `uv run --directory src`
for a `src` layout.

A missing `app.services` module or class stops the start with an `ImportError` that names the file to write where it
belongs, a package's `__init__.py` for a group you implement as a package; an import error inside your module, such
as a missing dependency, is raised as it is. A method whose signature cannot take the keyword arguments of its
operation stops the start with a `TypeError` that names the class, the method, and the argument; the check reads the
method's own signature, not that of a function a decorator wraps, and leaves its annotations unevaluated.

Open <http://127.0.0.1:8000/docs>. The page shows your `openapi.yaml`, not a document FastAPI derives from the
routes: the application serves the parts of the source document its operations use, the *served document*, at
`/openapi.json`.

### 6. Test it

FastAPI's `TestClient` calls the application without a server:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.test -->
<!-- fmt: off -->

```python
from fastapi.testclient import TestClient

from app.server.main import app

client = TestClient(app)


def test_create_and_get_pet() -> None:
    created = client.post("/pets", json={"name": "Mimi", "tag": "cat"})
    assert created.status_code == 201
    assert client.get(f"/pets/{created.json()['id']}").json() == created.json()


def test_missing_pet() -> None:
    response = client.get("/pets/99")
    assert response.status_code == 404
    assert response.json() == {"message": "Pet 99 not found"}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.test -->

```bash
uv add --dev pytest httpx2
uv run pytest test_app.py
```

### Recap

- The OpenAPI document is the source: the models, the routes, and the service Protocols come from it.
- `datamodel-codegen` regenerates every file of `app/models.py` and `app/server/` on each run.
- Your code lives in `app/services/`, outside the generated package, and subclasses the service Protocols, so type checkers keep it
  in step with the document; generation writes a missing module once, with stubs.
- `app/server/main.py` builds the application from your services with `create_app`, which tests and applications of your
  own can call with other instances.
- To call the server from Python, generate a client from the same document; see the
  [overview](index.md#generate-a-fastapi-server-or-an-http-client-experimental) and
  [Python Client Generation](python-client.md).

## Implement the services

The how-tos below build on a second project, a photo service, whose upload needs a bearer token:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.openapi -->
<details>
<summary>openapi.yaml</summary>

<!-- fmt: off -->

```yaml
openapi: 3.1.0
info:
  title: Pet photos
  version: "1.0"
paths:
  /pets/{petId}/photo:
    put:
      operationId: uploadPhoto
      tags: [photos]
      security:
        - bearer: []
      parameters:
        - name: petId
          in: path
          required: true
          schema: {type: integer}
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema: {$ref: "#/components/schemas/PhotoUpload"}
      responses:
        "201":
          description: Stored.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Photo"}
    get:
      operationId: getPhoto
      tags: [photos]
      parameters:
        - name: petId
          in: path
          required: true
          schema: {type: integer}
      responses:
        "200":
          description: The photo.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Photo"}
components:
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
  schemas:
    PhotoUpload:
      type: object
      required: [file]
      properties:
        file: {type: string, format: binary}
        caption: {type: string}
    Photo:
      type: object
      required: [petId, size, owner]
      properties:
        petId: {type: integer}
        size: {type: integer}
        owner: {type: string}
        caption: {type: string}
```

<!-- fmt: on -->
</details>
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.openapi -->

It adds two settings to the quick start's table, explained in [Async methods](#async-methods) and
[The request and per-request dependencies](#the-request-and-per-request-dependencies):

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.pyproject -->
<!-- fmt: off -->

```toml
[tool.datamodel-codegen]
server-include-request = true
server-handler-modes = '{"/paths/~1pets~1{petId}~1photo/put": "async"}'
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.pyproject -->

Its service Protocol takes the request, the authenticated principal, and an async upload:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.services -->
<!-- fmt: off -->

```python
"""Service interfaces of this package's router groups; regenerate them instead of editing."""

from __future__ import annotations

from abc import abstractmethod
from typing import Protocol

from app import models
from fastapi import Request
from fastapi.responses import Response
from typing_extensions import TypeVar

from ._runtime.server.responses import HTTPResult

PrincipalT_contra = TypeVar("PrincipalT_contra", contravariant=True)


class PhotosService(Protocol[PrincipalT_contra]):
    """Implement the photos operations: subclass this Protocol, or give an object its methods."""

    @abstractmethod
    async def upload_photo(
        self,
        *,
        request: Request,
        principal: PrincipalT_contra,
        pet_id: int,
        body: models.PhotoUpload,
    ) -> models.Photo | HTTPResult[models.Photo] | Response:
        """
        Handle PUT /pets/{petId}/photo.
        """

    @abstractmethod
    def get_photo(
        self,
        *,
        request: Request,
        pet_id: int,
    ) -> models.Photo | HTTPResult[models.Photo] | Response:
        """
        Handle GET /pets/{petId}/photo.
        """
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.services -->

### How methods and arguments are named

Methods and router modules are named in snake case, and Protocols in PascalCase, whatever the model naming options
say: a method after its operationId, or after its method and path without one, such as `get_pets_by_pet_id`.

A method's arguments are named after their wire names as model fields are, so the quick start's preset, which turns on
`--snake-case-field` for Pydantic models, names the `petId` path parameter `pet_id`. Without the preset, pass
`--snake-case-field` explicitly for snake_case arguments, or the argument keeps the wire name, `petId`. `--aliases` and
the special-field prefix options apply to arguments too.

A derived name that its namespace already holds takes the model's suffix, such as `id_1` for a query `id` beside a
path `id`, `body_1` for a parameter named `body`, or `pets_1` for a second tag that also becomes `pets`. The model's
`--naming-strategy` rules apply to these names too, with the router group as the parent of a method and the method as
the parent of an argument.

An explicit name of [`--server-operation-names`](cli-reference/target-generation-options.md#server-operation-names),
[`--server-router-names`](cli-reference/target-generation-options.md#server-router-names), or
[`--server-parameter-names`](cli-reference/target-generation-options.md#server-parameter-names) must be new and is
never renamed.

A schema written inline, rather than under `components`, takes a model name derived from where it is: its path, its
method, and its location. The path's words are joined in PascalCase without its separators, so `/pets/{petId}` gives
`PetsPetId`, the root path `/` gives `Root`, and only a path that starts with a digit, such as `/2fa`, is prefixed with
`Field` to stay a valid name. The tutorial's inline parameter schemas become these type aliases in `app/models.py`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.inline-names -->
<!-- fmt: off -->

```python
type PetsGetQueryLimitParameter = Annotated[int, Field(ge=1, le=100)]


type PetsPetIdGetPathPetIdParameter = int
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.tutorial.inline-names -->

An inline response schema of `GET /pets` would likewise become `PetsGetResponse`. The method arguments keep their
own names, `limit` and `pet_id`, but a body or response model is a class you import. To name such a model, declare its
schema under `components.schemas` and refer to it with `$ref`, as the tutorial does for `Pet`, `NewPet`, and `Error`.
A `$ref` beside only annotations, such as `description`, `title`, `examples`, or `x-` extensions, names that model too,
as it does for a property; one beside keywords that change its values, such as `minLength` or `nullable`, takes a
derived name. A parameter or body of such a `$ref` has the type and constraints of the component, as a bare `$ref`
does, so the service receives the component model, such as `Tags(root=[...])` for a `RootModel` component.

### Return values and `HTTPResult`

A service method returns the value of its primary response. FastAPI validates and serializes it with the route's
`response_model` when the response is JSON, by alias and leaving out unset fields.

`HTTPResult(status_code, body, headers)`, imported from the generated package (`from app.server import HTTPResult`), sends
another status or extra headers. For a status the operation declares, exactly, by its range such as `4XX`, or by
`default`, the package validates and serializes the body with that response's model and default media type, as
`get_pet` in the [quick start](#4-implement-the-operations) does.

A status the operation does not declare is sent unchecked: the body is encoded as JSON without validation, and
`HTTPResult(404)` without a body sends an empty `404`. A success status that declares content always sends content, so
`HTTPResult(200)` without a body sends `None` through that response's model; see [Responses](#responses).

Header names must be tokens and header values ASCII header text, as RFC 9110 writes them: tab, space, and visible
ASCII, without whitespace at either end, as the generated client sends them. A result with another header, such as
`headers={"X-Out": "café"}`, answers `500` with a `ResponseValidationError` that names the header.

A Starlette `Response` is sent as it is, for anything else, such as another media type or repeated headers. See
[Responses](#responses) for `null` bodies and empty responses.

### Raise errors

Raise FastAPI's `HTTPException` for an error the document does not describe. FastAPI answers with its own
`{"detail": ...}` body:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.errors -->
<!-- fmt: off -->

```python
    def get_photo(self, *, request: Request, pet_id: int) -> Photo:
        if (photo := self.store.photos.get((request.state.tenant, pet_id))) is None:
            raise HTTPException(404, f"Pet {pet_id} has no photo")
        return photo
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.errors -->

For an error the document declares, return an `HTTPResult` instead, so the body follows the declared model. Any other
exception answers an opaque `500`, as in any FastAPI application.

### Async methods

An operation's *handler mode*, `sync` or `async`, says whether its service method is a plain method or a coroutine
function. [`--server-handler-mode async`](cli-reference/target-generation-options.md#server-handler-mode) makes every
method a coroutine function, and
[`--server-handler-modes`](cli-reference/target-generation-options.md#server-handler-modes) sets the mode of single
operations, as the photo service does for its upload:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.async -->
<!-- fmt: off -->

```python
    async def upload_photo(self, *, request: Request, principal: str, pet_id: int, body: PhotoUpload) -> Photo:
        photo = Photo(pet_id=pet_id, size=len(body.file), owner=principal, caption=body.caption)
        self.store.photos[request.state.tenant, pet_id] = photo
        return photo
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.async -->

The setting names the operation by its *operation reference*, `/paths/~1pets~1{petId}~1photo/put`; see
[Per-operation settings](#per-operation-settings) for how to spell one. `create_app` and `build_router` refuse a
plain method for an `async` operation and a coroutine function for a `sync` one.

### The request and per-request dependencies

`build_router` takes FastAPI dependencies for every route as `dependencies`, which `create_app` passes to `FastAPI`,
and both take `operation_dependencies` for single operations, keyed by service method name, such as
`{"get_photo": [Depends(audit)]}`. The dependencies run before the method, but what they return never reaches it.

Give a service what it needs in one of two ways. Pass long-lived objects, such as a store or a database client, to
its constructor. For values of the request, generate with
[`--server-include-request`](cli-reference/target-generation-options.md#server-include-request), so that every method
receives the Starlette request as the keyword `request`, and let a dependency put values in `request.state`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.dependencies -->
<!-- fmt: off -->

```python
def tenant(request: Request, x_tenant: Annotated[str, Header()] = "public") -> None:
    request.state.tenant = x_tenant


class PhotoStore:
    def __init__(self) -> None:
        self.photos: dict[tuple[str, int], Photo] = {}


class Photos(PhotosService[str]):
    def __init__(self, store: PhotoStore) -> None:
        self.store = store


app = FastAPI()
app.include_router(build_router(photos=Photos(PhotoStore()), authorize=authorize, dependencies=[Depends(tenant)]))
app.add_exception_handler(RequestValidationError, validation_error_handler)
serve_source_openapi(app)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.dependencies -->

`tenant` reads a header the document does not declare and stores it for the methods, which keep the photos of each
tenant apart.

### Authenticate requests

The package of a document with secured operations declares one FastAPI security dependency for each scheme, in
`server/security.py`, and `create_app` and `build_router` take an `authorize` callback:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.authorize -->
<!-- fmt: off -->

```python
USERS = {"secret-token": "alice"}


def authorize(requirement_sets: RequirementSets, credentials: Credentials) -> str:
    bearer = credentials["bearer"]
    if isinstance(bearer, HTTPAuthorizationCredentials) and (user := USERS.get(bearer.credentials)):
        return user
    raise HTTPException(403, "Unknown token")


app = FastAPI()
app.include_router(build_router(photos=Photos(PhotoStore()), authorize=authorize, dependencies=[Depends(tenant)]))
app.add_exception_handler(RequestValidationError, validation_error_handler)
serve_source_openapi(app)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.authorize -->

A secured operation calls `authorize` with its requirement sets and the credentials each scheme presented, here an
`HTTPAuthorizationCredentials` under `bearer`. What it returns reaches the method as the keyword `principal`, and an
`HTTPException` it raises rejects the request. A request without credentials answers `401` before `authorize` runs.

The service Protocol of secured operations is generic in the principal type, so `Photos(PhotosService[str])` and an
`authorize` that returns `str` agree. [Security](#security) describes the schemes and the callback types in full.

Test it with headers, as for any FastAPI application:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.tests -->
<!-- fmt: off -->

```python
def test_upload_and_get_photo() -> None:
    uploaded = client.put("/pets/1/photo", headers=ALICE, files={"file": b"\x89PNG"}, data={"caption": "Rex"})
    assert uploaded.status_code == 201
    assert uploaded.json() == {"petId": 1, "size": 4, "owner": "alice", "caption": "Rex"}
    assert client.get("/pets/1/photo").json() == uploaded.json()


def test_credentials() -> None:
    assert client.put("/pets/1/photo", files={"file": b""}).status_code == 401
    wrong = {"Authorization": "Bearer wrong"}
    assert client.put("/pets/1/photo", headers=wrong, files={"file": b""}).status_code == 403
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.tests -->

### Accept uploads

A `multipart/form-data` body reaches the method as its model, with each file part read to `bytes`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.models -->
<!-- fmt: off -->

```python
class PhotoUpload(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    file: bytes
    caption: str | None = None
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.models -->

FastAPI reads forms with `python-multipart`, which the dependency notice adds for a document with forms:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.notice -->
<!-- fmt: off -->

```text
Add the runtime dependencies of app.server to your project:
  uv add "fastapi>=0.141.1" "pydantic>=2.14.0" "typing-extensions>=4.16" "python-multipart>=0.0.32"
Next steps: implement the stubs in app/services/photos.py, app/services/authorize.py, then run the server:
  uv add uvicorn && uv run uvicorn app.server.main:app --reload
or: uv add "fastapi[standard]" && uv run fastapi dev --entrypoint app.server.main:app
See app/server/README.md.
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.notice -->

A `format: binary` string is raw bytes, which only a whole body, such as `application/octet-stream`, `image/png` or
`text/csv`, or a file part of a multipart form can carry; a `text/*` body whose model types its whole value as one
binary string travels as its raw bytes, without a charset decoding or base64, as an `application/octet-stream` one
does. The model type decides: the schema is such a string, or reaches one through a `$ref`, a single `allOf`, `anyOf` or
`oneOf` branch, or `allOf` branches that merge into one, such as `allOf: [{type: string}, {format: binary}]`, also
beside a `null`, a length limit or other binary strings. The method takes and returns such a body as `bytes`, which its
model validates when it constrains them, such as `maxLength: 16` as `conbytes(max_length=16)`: a request body the model
refuses answers `422`, and a response body it refuses is not sent, as for any other body. Bytes the model leaves
unconstrained pass as they are, without a model call. An `enum` or a `const` of binary strings, also one that leaves
out `type: string`, is text in the models, so a body of one, also an `application/octet-stream` one, is read and sent
as text by its model, such as an `Enum`.
Generation stops with an error that names the operation, the media or parameter, and where the schema declares the
string, when a binary string, at any depth of its schema and through references, `$dynamicRef` and `allOf`, would be
read or sent as text: inside a JSON or URL-encoded body or response, also one whose model types its whole value as
bytes, a `text/*` body whose schema is an object, an array, or an `anyOf` or `oneOf` with a branch that is not a binary
string, a binary body, such as `application/octet-stream`, whose model types its whole value as bytes only in part,
such as `type: [string, integer]` or an `anyOf` of a binary string and an integer (`bytes | int`), a multipart part
that is not a file, an item of a streamed response, or a parameter or header. Pydantic writes `bytes` in JSON as
raw UTF-8 text, which other clients, such as a generated one with dataclass, TypedDict or msgspec models, write as
base64, and it cannot write bytes that are not UTF-8. Declare such a value `format: byte`, which every backend sends as
the same base64 text and Pydantic models hold as a `Base64Str`, or add
[`--type-mappings string+byte=binary`](cli-reference/typing-customization.md#type-mappings) to hold the decoded bytes as
a `Base64Bytes`, which also accepts bytes that are not UTF-8. Build a `Base64Bytes` field in Python from the base64
text, such as `base64.b64encode(data)`, not from the raw bytes: Pydantic decodes raw bytes leniently, so `b'\xff\x00'`
becomes `b''` without an error.

To stream a large upload or read the body yourself, generate the operation with
[`--server-body-modes`](cli-reference/target-generation-options.md#server-body-modes) set to `request`, or
[`--server-body-mode request`](cli-reference/target-generation-options.md#server-body-mode) for every operation: the
method then receives the raw Starlette request as the keyword `request` instead of a validated body.

### Use your own FastAPI app

`create_app` builds a FastAPI application and passes its other keyword arguments, such as `lifespan` or
`middleware`, to `FastAPI`. To keep an application of your own, include `build_router(...)`, as the photo service does:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.app -->
<!-- fmt: off -->

```python
from fastapi import Depends, FastAPI, Header, HTTPException, Request
from fastapi.exceptions import RequestValidationError
from fastapi.security import HTTPAuthorizationCredentials

from app.models import Photo, PhotoUpload
from app.server import Credentials, RequirementSets, build_router, serve_source_openapi, validation_error_handler
from app.server.services import PhotosService


app = FastAPI()
app.include_router(build_router(photos=Photos(PhotoStore()), authorize=authorize, dependencies=[Depends(tenant)]))
app.add_exception_handler(RequestValidationError, validation_error_handler)
serve_source_openapi(app)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.howto.app -->

`build_router` takes the services, `authorize`, `dependencies`, `operation_dependencies`, and `prefix`. Two things
that `create_app` does are then yours to add:

- `serve_source_openapi(app, prefix=..., metadata=...)` serves the source document instead of FastAPI's own; pass the
  prefix the router is included under and the description settings to replace.
- `app.add_exception_handler(RequestValidationError, validation_error_handler)` keeps the rejected values out of
  validation errors; see [Production settings](#production-settings).

## Regenerate after the document changes

Run the same command again after the OpenAPI document changes. The service Protocols change with the operations, so
type checkers point at the implementations to update, and Python refuses to create an instance of a subclass that
lacks a new method. Modules outside the package are never rewritten: generation writes a module of `services` only
while it is missing, so a new router group gets its module with stubs, and the module of a renamed or removed group
stays for you to move or delete.

Generation renders every file first and then *publishes* them: it writes the changed files together and rolls back
earlier changes if a write fails. A file that already holds its generated bytes is not rewritten. Like the models,
every file of the package is written as text with the line ending of the platform, CRLF on Windows and LF elsewhere.

Every generation overwrites every generated file of the package, restoring any you edited or deleted. A file that is
no longer generated, such as the router module of a removed tag, stays until you delete it, and `--check` lists it as
an extra file. A generation that leaves such `.py` files in place names them in one `LeftoverFilesWarning`, which
points code of your own at `services`; Python
shows once per process for the same text, also under `--watch` and repeated `generate()` calls. Silence exactly this
warning with `warnings.simplefilter("ignore", datamodel_code_generator.LeftoverFilesWarning)` around `generate()`, or
with `ignore::datamodel_code_generator.LeftoverFilesWarning` in pytest's `filterwarnings`.

### Check in CI

`--check` renders everything without writing it and exits with 0 when nothing would change, 1 when a file would
change, such as a generated file you edited or deleted or a file that is no longer generated, and 2 for an error. In
Python, compare the files `generate()` returns without an `output`.

`--check` uses the model output comparison: it prints unified diffs and missing or extra file messages to stdout.
It compares the rendered model and server text, including the README and `py.typed`, plus extra `.py` files under
the model and server output directories. CRLF and LF compare equally. Unrelated text files are outside this scope, and
so are the modules of `services`: a check neither reports one that is missing nor lists one as extra, even inside a
model directory. `--check --output-format json` uses the same check payload as model generation. Checking publishes
nothing, and neither does `--diff-against`.

The models and the server files keep the generation timestamp unless `--disable-timestamp` or a preset that sets it
leaves it out, as for model generation; one run heads every file with the same timestamp. Without the timestamp, a
run on unchanged inputs reproduces every byte: it writes nothing, and `--check` exits with 0, also from another
directory when the paths name the same input and outputs.

### Compare and watch

`--diff-against OLD_INPUT` renders the models and the server from both inputs without writing anything, and prints
what changes between them with the model input diff: unified diffs labeled `(baseline input)` and `(current input)`,
and files generated only from one of the inputs. It exits with 0 when both render the same files and 1 otherwise;
`--output-format json` emits the model input-diff payload.

`--watch` regenerates the models and the server whenever the input, a document it references, or a file an option
names changes, as for model generation. It needs the `watch` extra, `datamodel-code-generator[watch]`, and has the same
limits: it needs a local `--input` and cannot be combined with `--check` or `--output-format json`.

### JSON output and the lock file

`--output-format json` publishes the files and emits the existing generation payload as one JSON document on
stdout. Its `output` is the configured model output; `files` contains the rendered model and server text. As in
the model payload, a file path is relative to the model output directory, which is `output` for a model directory
and its parent for a single model file, so `output` and the path give the file on disk. A file outside that
directory, such as a server package beside a model directory, has an absolute path. Paths use forward slashes.
`--check --output-format json` names the files the same way in `differences[].path`, while the diff labels stay
relative to the working directory. Model metadata and the remote lock are outside the payload, as for model
generation. The dependency notice and the next steps go to stderr, along with errors and Python warnings; the
generation, check, and input-diff payloads carry the same requirements in `target`, next to the package's import
path, so a tool can read them without parsing stderr. The generation payload adds the next steps: the package
`readme`, the `entrypoint` module and the import string of its application, and the `implementation` modules it
imports, with `created` true for each module this run wrote with stubs. Their paths are relative like those of `files`:

```json
"target": {
  "package": "app.server",
  "dependencies": ["fastapi>=0.141.1", "pydantic>=2.14.0", "typing-extensions>=4.16"],
  "readme": "server/README.md",
  "entrypoint": {"app": "app.server.main:app", "path": "server/main.py"},
  "implementation": [{"module": "app.services.pets", "name": "Pets", "path": "services/pets.py", "created": true}]
}
```

`files` holds the generated files only, not the stubs of `services`. A check or an input diff lists the requirements
of the current input; payloads of model-only jobs have no `target`.

The remote lock file takes part as it does for model generation, when `--lockfile` names it, `--update-lock` or
`--locked` uses it, or the default `datamodel-codegen.lock` exists. As for model generation, it must not overlap the
input or the model output, and it must lie outside the server output directory; a run with such a lock path stops
before it generates anything.

Several targets can share one models module: with the same input, whose file name the model header records, the
same model options, including the same `--openapi-include-paths`, and `--disable-timestamp`, each run writes the same
bytes, and `--check` reports a module that differs.

## Configure generation

### Requirements

Server generation needs some model settings. A setting you leave unset, on the command line, in
`[tool.datamodel-codegen]` or a job's table, in the arguments of `generate()`, and in the preset, takes the value
the server needs; a value you set yourself that the server cannot use stops the run with `Error:` and exit code 2,
or an `Error` from `generate()`. The model options that depend on these settings, such as `--use-specialized-enum`
on the target Python version, see the values the server sets. The models are those of a model-only run given the same
settings. After a command line run that set any, stderr shows how to set them yourself, before the `uv add` notice:
the command as you ran it with the options appended, when the command line selected the target or no
`pyproject.toml` was read (noting an input read from stdin), or else the lines to add to the table that held the
settings: the job's table for a job, the profile's for `--profile`, quoted as TOML needs, in the `pyproject.toml`
named by its path from the working directory. `--watch` shows them once, after its first generation.
`--output-format json` names them in `target.implied`, an object whose keys are those of `pyproject.toml`:
`openapi-scopes`, `target-python-version`, `use-missing-sentinel`, `target-pydantic-version`,
`use-msgspec-tagged-unions`, and `use-msgspec-nullable-enum-alias`, each present only when the target set it.
`generate()` prints nothing. Presets stay as they are, without these settings.

- Python 3.11 or later, both to run `datamodel-codegen` and as the target Python version: an unset
  `--target-python-version` is `3.11`. An older one, set yourself or by a preset for Python 3.10, is refused; the
  message names the preset, so that you pick one for Python 3.11 or later. Running on Python 3.10 is refused too.
- `--openapi-scopes` includes `api`, so that the models cover the parameters, bodies, and responses of the
  operations: unset, it is `schemas api`. Scopes you give without `api` stop the run with
  `Error: --generate-server requires --openapi-scopes to include api`.
- `--use-missing-sentinel` needs `--target-pydantic-version 2.14`, with which the models import `MISSING` from
  `pydantic` (`from pydantic import MISSING`): with the sentinel, an unset target is `2.14`. Model generation alone
  imports it from `pydantic.experimental.missing_sentinel`, which pydantic 2.14 deprecates, when the target is unset
  or `2.12`, and refuses the option for `2` and `2.11`. With a target of `2`, `2.11`, or `2.12` that you set, server
  generation stops with `Error: The fastapi target needs --target-pydantic-version 2.14 for --use-missing-sentinel,
  so that the models import MISSING from pydantic`.
- `pydantic_v2.dataclass` models need `--use-missing-sentinel`, and with it `--target-pydantic-version 2.14`, since a
  dataclass field cannot tell an unset member from one set to `None`: unset, the sentinel is on and the target is
  `2.14`; a target pydantic version older than `2.14` that you set is refused with a message that says the server
set the sentinel. With `use-missing-sentinel = false` in `pyproject.toml`, generation stops with
  `Error: The fastapi target needs --use-missing-sentinel with --target-pydantic-version 2.14 for
  'pydantic_v2.dataclass' models, whose fields cannot tell an unset member from None`. With both, an optional field
  without a default holds `MISSING`: a member a request leaves out reaches the method as `MISSING`, and a field the
  method leaves unset is left out of the response.
- The input is one OpenAPI 3.0, 3.1, or 3.2 document, from a file, a URL, or stdin; a directory or a list of
  files is refused.
- `--output-model-type` is `pydantic_v2.BaseModel` or `pydantic_v2.dataclass`; the other backends are
  refused. Custom templates, base classes, and types do not add backends.
- The model options apply as they do without `--generate-server`, so the same options write the same model files
  (only the command `--enable-command-header` records differs), and a model option the model generation refuses,
  such as `--collapse-root-models-name-strategy` without `--collapse-root-models`, is refused before anything is
  written.
- The server files are headed, formatted, and encoded like the model files, by the same model options:
  `--formatters` (including its default and warning), `--custom-formatters` and `--custom-formatters-kwargs`,
  `--custom-file-header`, `--custom-file-header-path` and `--custom-file-header-mode`, `--disable-timestamp`,
  `--enable-version-header`, `--enable-command-header`, `--use-double-quotes`, `--builtin-format-line-length`,
  `--encoding` (for the Python files; the other files are UTF-8), `--use-type-checking-imports`, and the formatter
  settings found from `--output`. The target settings have no output options of their own. As for the models, Ruff
  moves imports only an annotation uses into `TYPE_CHECKING` blocks when `ruff-check` runs with its TC rules
  selected and `--use-type-checking-imports` is given, since the server's Pydantic backends keep them by default. The
  router and application modules keep their imports: they have no postponed annotations, because FastAPI reads them
  at run time. As for the models, `typing.get_type_hints` on a generated class or function whose annotations name a
  moved import then raises `NameError`: pass `--no-use-type-checking-imports`, or do not select the TC rules, to
  introspect the annotations at run time.
- Custom templates and custom formatters must keep the class and field names of the models: the server binds each
  operation to the names in the generated model graph and does not read the rendered model source.
- `--output` names the model file or package, and `--server-model-package` is its import path. The models can
  live inside the server package, and the server package inside a models directory; see
  [The generated package](#the-generated-package).
- The generated package needs `fastapi>=0.141.1` and the other requirements of the printed `uv add` command.

### Server options

Every server setting is a command-line option and a `[tool.datamodel-codegen]` key of the same name, like the
model options, so profiles, `--ignore-pyproject`, `--generate-pyproject-config`, and `--generate-cli-command`
work for them as well. Each option links to its examples in the CLI reference.

| Option | Default | Meaning |
| --- | --- | --- |
| [`--generate-server fastapi`](cli-reference/target-generation-options.md#generate-server) | off | Generate the server package with the models |
| [`--server-output`](cli-reference/target-generation-options.md#server-output) | required | Directory of the generated package |
| [`--server-package`](cli-reference/target-generation-options.md#server-package) | required | Import path of the generated package |
| [`--server-model-package`](cli-reference/target-generation-options.md#server-model-package) | required | Import path of the models `--output` generates |
| [`--server-layout`](cli-reference/target-generation-options.md#server-layout) | `routers` | One router module per group, or `single` for one `routes.py` |
| [`--server-handler-mode`](cli-reference/target-generation-options.md#server-handler-mode) | `sync` | `async` makes service methods coroutine functions |
| [`--server-handler-modes`](cli-reference/target-generation-options.md#server-handler-modes) | none | The handler mode of single operations, over `--server-handler-mode` |
| [`--server-include-request`](cli-reference/target-generation-options.md#server-include-request) | off | Pass the Starlette request to every service method as the keyword `request: Request` |
| [`--server-body-mode`](cli-reference/target-generation-options.md#server-body-mode) | `typed` | `request` passes the raw request, as the keyword `request: Request`, instead of a validated body |
| [`--server-body-modes`](cli-reference/target-generation-options.md#server-body-modes) | none | The body mode of single operations, over `--server-body-mode` |
| [`--server-primary-responses`](cli-reference/target-generation-options.md#server-primary-responses) | inferred | The response a bare return value takes: `status_code` and an optional `media_type` |
| [`--server-operation-names`](cli-reference/target-generation-options.md#server-operation-names) | inferred | Service method names of single operations |
| [`--server-router-names`](cli-reference/target-generation-options.md#server-router-names) | inferred | Group keys, such as `tag:pets` or `default`, to group names: router modules, service arguments, and `<Name>Service` Protocols |
| [`--server-parameter-names`](cli-reference/target-generation-options.md#server-parameter-names) | inferred | Method argument names of single operations, keyed by location and name such as `query:limit` |

On the command line, `--generate-server` requires `--server-output`, `--server-package`, and `--server-model-package`,
and a `--server-*` option requires `--generate-server`; both stop with `Error:` and exit code 2. In Python,
`generate()` needs `server_output` only with an `output`; see [Python API](#python-api). Server keys of
`pyproject.toml` are validated like model keys, but have no effect while no server is selected.
`--generate-server` also requires `--input-file-type openapi`: an input type left to detection, `auto`, or any other
type stops with `Error: --generate-server requires --input-file-type openapi, not auto` (naming the given type) and
exit code 2 before the input is read.

Operations are grouped by their first tag, under the key `tag:<tag>`, and operations without a tag under the key
`default`, which makes the `default` router module, the `DefaultService` Protocol, and the `default=` argument of
`create_app` and `build_router`; the generated client calls the same operations `client.default`. A tag whose name
also derives `default`, such as `default` or `Default`, is another group: on the server and the client alike, the
one declared first keeps `default` and the other takes a number, such as `default_1`, as other derived names do.

With `--server-layout single`, every operation is in the group `all`: one `routes.py`, one `Service` Protocol, and the
argument `service=`. `--server-router-names '{"all": "store"}'` renames it, as other group keys are renamed, to
`StoreService` and `store=`. A group key that matches no group stops the run with an error, as an operation reference
that names no operation does.

`--server-parameter-names` keys an argument by its location, `path`, `query`, `querystring`, `header`, or `cookie`,
and its wire name, such as `query:limit`.

`--server-handler-modes`, `--server-body-modes`, `--server-primary-responses`, `--server-operation-names`,
`--server-router-names`, and `--server-parameter-names` take a JSON object, inline or as the path of a JSON file, as
`--aliases` does. In `pyproject.toml` they are tables, or JSON strings, as the [how-to project](#implement-the-services)
writes `server-handler-modes`; `--generate-pyproject-config` writes them as JSON strings, and `--generate-cli-command`
prints them as JSON, as for the model options that take JSON objects.

A value on the command line takes precedence over the selected profile, which takes precedence over the base table,
and a command-line table replaces the whole table of `pyproject.toml`. An operation's own entry takes precedence over
the global setting, wherever each comes from. Paths in `pyproject.toml`, including the JSON files of these settings,
are relative to its directory, and command-line paths are relative to the working directory. The documents of
operation references are relative to the JSON file that holds them, however the file is given, and to a symbolic
link's directory when the file is given through one; without a file, to the `pyproject.toml` directory for its tables,
and to the working directory for inline JSON on the command line.

The package serves every operation under `paths` of the input; a path item under `components.pathItems` that no
path references has no URL and is not served. To leave paths out, pass
[`--openapi-include-paths`](cli-reference/openapi-only-options.md#openapi-include-paths). The models follow the
`api` scope as in a model-only run: inline schemas of the paths left out are not generated, while the schemas and
path items under `components` still are. A per-operation setting that names a path left out fails with
an error before generation.

Callbacks and webhooks of the document appear only in the [served document](#served-openapi-document): the package
generates no routes and no service methods for them.

### Per-operation settings

Per-operation settings are keyed by *operation reference*: the JSON pointer of the path item method in the input
document, or a document and a pointer joined by `#`, such as `pets.yaml#/paths/~1pets/get`.

A JSON pointer joins the keys from the document root with `/`, so a key that itself contains `/` or `~` is escaped:
`~` becomes `~0`, and then `/` becomes `~1`. The path `/pets/{petId}` is the key under `paths`, so the `get` operation
of it is `/paths/~1pets~1{petId}/get`. The README of the generated package lists the reference of every operation.

These settings decide the generated code, including each method name, so they name an operation as the input
document does; `operation_dependencies`, an argument of the generated package, names it by its method.

```toml
[tool.datamodel-codegen.server-handler-modes]
"/paths/~1pets/get" = "async"

[tool.datamodel-codegen.server-body-modes]
"/paths/~1upload/post" = "request"
```

```bash
datamodel-codegen --server-handler-modes '{"/paths/~1pets/get": "async"}'
```

### Python API

`generate()` takes the settings of the [quick start](#2-generate-the-server) as keyword arguments: the server
options under their Python names, with the model options; the choices are enums of `datamodel_code_generator` such as
`ServerType` and `ServerHandlerMode`, whose string values also work, and the JSON options take mappings keyed by the
same operation references:

<!-- BEGIN AUTO-GENERATED FASTAPI PYTHON API -->
```python
from pathlib import Path

from datamodel_code_generator import DataModelType, InputFileType, OpenAPIScope, ServerType, generate

generate(
    Path("openapi.yaml"),
    input_file_type=InputFileType.OpenAPI,
    openapi_scopes=[OpenAPIScope.Schemas, OpenAPIScope.Api],
    output_model_type=DataModelType.PydanticV2BaseModel,
    preset="standard-py312-20261015",
    output=Path("app/models.py"),
    generate_server=ServerType.FastAPI,
    server_output=Path("app/server"),
    server_package="app.server",
    server_model_package="app.models",
)
```
<!-- END AUTO-GENERATED FASTAPI PYTHON API -->

It publishes the models and the package together and returns `None`, like model generation. Without an `output`, it
needs no `server_output`, returns every model and server file as `GeneratedModules`, under the paths their import paths
imply, such as `("app", "models.py")` and `("app", "server", "application.py")`, and writes nothing but the model
metadata and a remote lock update; see
[Generating a Server or Client Package](using_as_module.md#generating-a-server-or-client-package).
With an `output`, it writes the missing modules of `app.services` with stubs, as the command line does; without one,
it writes and returns none.

`load_pyproject_config()` reads the server keys of `pyproject.toml`, whose paths and operation documents resolve
against its directory. Invalid settings, bindings, and template failures raise `datamodel_code_generator.Error` with
the message the command line prints. The `uv add` notice and the next steps are command-line messages only.

### Batch jobs

A [named job](pyproject_toml.md#named-jobs-experimental) whose settings select the server generates it as a single run
with the same settings does, so one `pyproject.toml` can describe model-only jobs and server jobs together. Put
`generate-server` in each server job or in a profile it selects, not in the base table, when other jobs generate
models only.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.batch-jobs -->
<!-- fmt: off -->

```toml
[tool.datamodel-codegen]
input-file-type = "openapi"
output-model-type = "pydantic_v2.BaseModel"
openapi-scopes = ["schemas", "api"]
preset = "standard-py312-20261015"
disable-timestamp = true

[tool.datamodel-codegen.profiles.server]
generate-server = "fastapi"
server-package = "app.server"
server-model-package = "app.models"

[tool.datamodel-codegen.jobs.schemas]
input = "openapi.yaml"
output = "client/schemas.py"

[tool.datamodel-codegen.jobs.server]
profile = "server"
input = "openapi.yaml"
output = "app/models.py"
server-output = "app/server"
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.batch-jobs -->

```bash
datamodel-codegen --all-jobs
datamodel-codegen --job server --server-handler-mode async
datamodel-codegen --all-jobs --check
```

A server option on the command line applies to every selected job and takes precedence over the job table, its
profile, and the base table, as a model option does; every selected job must then select the server.

`server-output`, like `output`, must not overlap the outputs of other jobs or contain the remote lock file. Server
jobs can share their models, though: jobs that each select the server may name the same `output`, which the batch
writes once. They must generate the same models for it, so give them the same input and model settings; a model-only
job cannot share its `output`. The server jobs of a batch write one generation timestamp, unless
`--disable-timestamp` leaves it out, as it does here so that `--check` compares equal.

The batch publishes the server packages together with the models of every job once all jobs succeed, and publishes
nothing when a job fails or when jobs generate different models for a shared `output`; the `uv add` notice and the
next steps of each package follow the publication on stderr. A parent package holds one server: two server jobs
whose packages share a parent package would import their implementations from one `services` package, so the batch
refuses them and writes nothing, whatever router groups they have. `--check` compares every job as a single run
does and exits with 1 when any of them would change. With `--output-format json`, a server job adds the generation or
check payload of a single server run to the batch document, with file paths relative to that job's model output
directory. `--all-jobs --watch` regenerates the batch, server jobs included, whenever an input any job read changes.

### The generated package

| Path | Contents |
| --- | --- |
| `__init__.py`, `application.py` | `create_app`, `build_router`, `HTTPResult`, and the other public types |
| `main.py` | The application: `create_app` with an instance of each implementation of `services`; the package initializer does not import it |
| `services.py` | One service Protocol per router group, with an abstract method per operation |
| `routers/` or `routes.py` | Route registrations |
| `security.py` | One FastAPI security dependency for each scheme, only when a selected operation uses a security scheme |
| `_generated/`, `_runtime/` | Plans and the runtime the package imports |
| `README.md`, `py.typed` | Documentation and typing marker |

Keep the service implementations and the `authorize` callback in the `services` package beside the server package,
which `main.py` imports: `services` beside `server`, `app/services` for `--server-package app.server`, written by
generation only while a module is missing. Each stub names the server package it was written for, and the docstring
of `services/__init__.py` records the server package that owns the `services` package. One parent package holds one
server package: generation refuses a second server package beside a generated one, in a later run or in the same
batch, since its `main.py` would import the same `services` package, whatever its directory, whether its `main.py` is
still there, and whatever the docstring of `services/__init__.py` says; give each server package a parent package of
its own, or delete the directory of the other one when it is no longer used. A server package that you rename or move
within its parent package, or name from another import root, such as `app.server` after `src.app.server`, takes the
`services` package over while no other generated server package is beside it. Generation then rewrites the name in the
docstring, `--check` reports the change, and the run prints a notice that names both packages. Generation never
rewrites the modules of the `services` package, which still import the server package they were written for, such as
`from app.server.services import PetsService` after a rename to `app.api`: update those imports yourself.
Generation also refuses a module named `services.py` beside the server package, a module of yours or the models, since
Python would import only one of it and the `services` package. An application of your own, such as one with a
`lifespan`, also belongs outside the package and calls `create_app` itself. `--check` treats every `.py` file under `--server-output` as
generated, lists a file that is no longer generated as an extra file, and a file at a path the package needs is
overwritten.

The models can be part of the package. Name a model file or directory inside `--server-output` and its import path:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.nested-models.command -->
<!-- fmt: off -->

```bash
datamodel-codegen \
  --input api.yaml \
  --input-file-type openapi \
  --output app/server/models.py \
  --output-model-type pydantic_v2.BaseModel \
  --preset standard-py312-20261015 \
  --openapi-scopes schemas api \
  --generate-server fastapi \
  --server-output app/server \
  --server-package app.server \
  --server-model-package app.server.models
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.nested-models.command -->

The server package can also sit inside a models directory. Either way `--check` compares the outer directory once,
so it reports each file once. A model file and a server file that would take the same path stop the run with an
error, and so does a module with the name of a generated package directory beside it, such as `server/routers.py`
beside `server/routers/`, which Python would import instead of the module. A job can nest its own `output` and
`server-output` in the same way.

## Reference

### Request handling

The generated models are the runtime contract. Routes declare the model types directly: a JSON body is
`Annotated[Model, Body()]` unless an adapter reads it, as below, a URL-encoded form of a `BaseModel` is a FastAPI form
model, a primary JSON response is `response_model=Model`, and path, query, header, and cookie parameters are
`Annotated` FastAPI parameters of the parameter's model type. A parameter's root model or type alias is unwrapped to
its type when that type alone validates the same, so the method receives the value.

An optional parameter or request body that the request omits arrives as `None`, and a parameter with a default as its
default. The routes declare such an input as FastAPI applications do, `T | None = None`, so FastAPI's own document
shows its schema as `anyOf` of the type and `null`. A default that the parameter's schema declares reaches the method
whenever the request omits the parameter, however the model options spell the type, such as with `--use-annotated` or
`--field-constraints`; a parameter whose type stays a root model receives that model with its own default. How
strictly a value follows the OpenAPI document is decided by the model generation options, not by the server.

A path parameter is required, as OpenAPI requires, even when the document leaves out `required` or declares it
`false`, and a default it declares is not used; the served document keeps the declaration as written. A document with
a path parameter that names no placeholder of its path is refused. A `content` key of a request body or a response
that is no media type, such as `multipart/form data`, stops generation with
`The media type 'multipart/form data' of POST /p is not a media type`, as it does for the generated client. So does a
media type whose text is not ASCII header text, such as `text/plain; label="café"`, since no Content-Type header
carries it.

FastAPI cannot read some inputs, so a generated *adapter* reads them and validates the result with the model's
`TypeAdapter`: deepObject, label, matrix, spaceDelimited, and pipeDelimited parameters, parameters with `content`,
cookie arrays, header and path arrays, objects, enums and literals of non-string values, strict integers,
numbers, and booleans (`--strict-types`), repeated path placeholders, request bodies with several media types, text
and binary bodies, multipart forms, and forms of the `pydantic_v2.dataclass` backend. A multipart form body reaches
the method as its model, with uploads read to `bytes`.

FastAPI takes the JSON `null` of a required body for an omitted one, so an adapter also reads a required JSON body whose
model type accepts `null`, such as a `nullable: true` string, a union with `null`, a schema of any value, or an
`x-python-type` that does, such as `typing_extensions.Any` or `typing.Literal['ok', None]`: the method receives what the
model validates `null` as, `None` or the root model that holds it. `--force-optional` makes every root model and type
alias accept `null`, so every required JSON body of one, such as a string, an array, or a union, is read this way. A
required JSON body whose type rejects `null` stays FastAPI's and answers `null` with a `missing` record at `["body"]`,
and an optional one stays FastAPI's too: its method receives `None` for `null` as for an omitted body. An adapter that
reads a JSON body for another reason, such as several media types, reads a `null` its model rejects the same way: `422`
with a `missing` record at `["body"]` for a required body, and `None` for an optional one, with `None` as the media
type, as for an omitted body.

A body that an adapter reads needs a Content-Type the operation declares: `application/json` with or without
parameters for a body declared as `application/json`, but not another `+json` type, which FastAPI's own reading
accepts. A request with any other Content-Type, or with a body and none, answers `415`. For a required body, so does
an empty body with an undeclared Content-Type, while an empty body without a Content-Type, or with a declared JSON
one, answers `422` with a `missing` record at `["body"]`. The JSON is read as UTF-8 without a byte order mark: a body
that starts with one, or is UTF-16, answers `422` with `json_invalid`, where FastAPI's own reading accepts both.

A multipart part is text when the type of its member, or of the member's items when that type is an array, has one
scalar kind, with one part for each item of an array. A part of any other member is JSON, as the generated client sends
it: an object, a mapping, each item of an array of objects, a union of a string and an object, an enum of mixed kinds,
or a union of an array and another type, whose array is one part. So is a part of a member whose `encoding` names one
JSON media type, such as `contentType: application/json`, and no style that applies (OpenAPI 3.0 ignores a multipart
style), a scalar included, and of a member without a type, whose schema is `{}`, or of each item of an array whose items
have none. A JSON part is parsed by `TypeAdapter.validate_json` whatever media type the part names and whether it
arrives as a field or as a file, since the server cannot see the media type of a part that is not a file: of the
member's model field, so the field's own constraints and `discriminator` apply and a tag no member of the union has
answers one `union_tag_invalid` record, or, for a member that repeats, of its items' type. A part that is not JSON, or
that the type rejects, answers `422` with its records at `["body", name]`, or at `["body", name, index]` for a member
that repeats, before the rest of the body is validated. A member without a type takes any value, so it keeps a part that
is not JSON as it arrives instead: text for a field, bytes for a file. An `encoding` can also name one text media type
in UTF-8 or US-ASCII, or in no charset, for a member of one scalar kind, such as
`contentType: text/plain; charset=utf-8`, and any media types for a member holding files, such as `image/png`: the parts
are read as they are without one, since Starlette reads every field part as UTF-8 text and keeps the bytes of a file,
whatever media type the part names.

Starlette limits what it reads from a multipart form, and the generated client sends a JSON part as a field: a field
part of more than 1 MiB (`max_part_size`) answers `400` with `Part exceeded maximum size of 1024KB.`, and so do more
than 1000 fields or 1000 files. FastAPI's own `Form()` parameters have the same limits. Neither FastAPI nor Starlette
has an application setting for them; only `await request.form(max_part_size=..., max_fields=..., max_files=...)` takes
them, which a method of `--server-body-mode request` can call. A part with a filename is a file to Starlette, which
does not limit its size. Starlette decodes a field part with the charset of the request's Content-Type, UTF-8 when it
names none, and as Latin-1 only when that decoding fails, so such a part is accepted and read as Latin-1 text.

A schema can type the properties it does not declare, with `additionalProperties: {...}`. Their parts come under any
name no declared member has and are read by the same rule, by the type the model keeps their values as, in a field of
its own or one it inherits from a schema combined with `allOf`: text of that type's kind, a list with one part for
each item of an array, or JSON, whose records name the part as a declared member's do. So are their fields in a
URL-encoded form, which an adapter then reads. A model that validates its fields by name too, such as one
`--allow-population-by-field-name` configures, also takes a part or field named like a property's field, such as
`max_age` beside `maxAge`, as that property, unless another property has that name; any other name is one of the
other properties. Other properties the schema allows without a type, with `additionalProperties: {}`, `true`, or no
`additionalProperties`, are values without a type like a member without one: a part under a name no declared member
has is JSON, the last of its name, kept as it arrives when it is not JSON, and in a URL-encoded form a field is text.
The model keeps such a value, ignores it, or refuses it, as its options and `additionalProperties: false` say. The
`pydantic_v2.dataclass` models have no field for other properties, so the
server reads typed ones by the type their schema gives them, the form's own or that of a schema it combines with
`allOf`, also when `--reuse-model` makes the form's model inherit an equal one whose schema types them otherwise. That
type checks JSON parts and text alike, answering `422` with the records of every value it rejects at `["body", name]`,
and the model keeps each value as the type returns it, as an attribute beside its fields, which its `repr` leaves out.

A URL-encoded form carries text alone. For a member without one scalar kind, such as an object, an array of objects,
or `type: [integer, boolean]`, declared by the schema or by a schema it combines with `allOf`, generation stops with
`A parameter value needs one unambiguous scalar kind`, as it does for the generated client and for a parameter,
unless an `encoding` gives the member a style or content. It stops the same way, at the `additionalProperties` that
types them, for other properties of such a type, with either backend. The generated client stops for these members
and other properties with the same message at the same place. Both also refuse a URL-encoded body whose schema has
`patternProperties` (`Pattern properties have no builtin parameter encoding`) or is not an object, such as an array,
a string, or `properties` without `type: object` (`A URL-encoded value must be an object`), unless the request body
mode reads it.

A form body whose schema is a union of one schema and `null` alone, such as
`anyOf: [{$ref: "#/components/schemas/Search"}, {type: "null"}]`, is read as the form of that schema, its members and
other properties by the rules above, and the model that holds it receives the object. A multipart body whose schema
is a union of several schemas declares no members its parts could be read by: generation stops with
`needs body_mode='request'`, as the generated client stops with `needs an object schema to be sent as parts`.

An adapter reads a form member whose `encoding` names a `style`, `explode`, or `allowReserved` as the generated
client writes it: as the query parameter that encoding describes, the way a query reads one. OpenAPI 3.0 applies these
fields to a URL-encoded body alone and ignores them for `multipart/form-data`, whose member is then read as one without
them, in its `contentType`; OpenAPI 3.1 and 3.2 apply them to both. An object with `style: form` and `explode: true`,
the default of an encoding that names only `explode`, comes as the pairs or parts of its own members, which it takes
back: the names its schema declares and, when it allows other properties, any name that no other member of the form
has. A `deepObject` comes as `name[key]` pairs or parts, and `form` without explode, `spaceDelimited`, and
`pipeDelimited` as one delimited pair or part. A URL-encoded pair is percent-encoded; a part carries the style's text
without percent-encoding, as OpenAPI 3.2 requires, so `allowReserved` changes no part, and the client refuses a
delimited value that holds its style's delimiter (`,`, a space, or `|`) before it sends it. A URL-encoded member's
`contentType` without a style sends it as one pair of text, or of JSON that is parsed as a JSON part is, with records at
`["body", name]`. The other pairs and parts are read as in a form without such members, and the model validates the
result; an operation with such a member is an adapter's, not FastAPI's form model. An encoding that the client has no
form for, such as `deepObject` for an array or `contentType: application/xml` in a URL-encoded body, stops generation
with the message the client stops with. So does a form whose exploded object that allows other properties shares the
form with another such member, a `deepObject` member, or other properties of its own that its schema allows with
`additionalProperties` as `true` or a schema, or that its Pydantic model keeps by its configuration, such as
`--extra-fields allow`, since both would take the same names, as an operation's query parameters are refused.

The adapters read no part headers, no multipart `encoding` that names another media type, such as one in another
charset or `application/xml` for a member without files, and no style for a member holding files, which the client
refuses too: generation stops with an error that names the encoding. In OpenAPI 3.1 and 3.2 a style leaves a
multipart member's `contentType` unused, as it does for the client. `--server-body-mode request` passes any such body
to the method unread.

The router splits a request path at the slashes the request sends, so a percent-encoded slash (`%2F`) stays inside
its path parameter, whose value receives `/`, of whatever style; FastAPI alone routes by the decoded path, where
`%2F` would end the segment. A path without an encoded slash is routed as FastAPI routes it, and so is one that
selects a route you add to the generated router yourself, such as a mount or a Starlette route.

!!! warning
    A path parameter value can therefore contain `/` and `..`: `..%2F..%2Fetc` arrives as `../../etc`. Validate such
    a value, for instance with a `pattern` in the schema, before using it as a file system path or in another URL.

A path's literal text is routed by its decoded value, as Starlette matches the decoded path: the document path
`/files/a%20b` registers the route `/files/a b`, which the request `/files/a%20b` of the generated client matches,
while the served document keeps the path as written. Literal text that encodes `/`, `{`, or `}` (`%2F`, `%7B`, or
`%7D`) stops generation with an error, since no route matches it. So do two operations of one method whose paths
route alike once decoded, such as `/a b` and `/a%20b`.

A cookie parameter with a single value is a FastAPI `Cookie`, whatever its style, so the method receives the value
as the request sent it: nothing is percent-decoded (`a%20b` stays `a%20b`), a value in double quotes loses the
quotes, a `;` ends the value, and the last of several cookies of one name is taken. The generated client sends such
values as they are, too, and generation stops with an error for such a cookie whose name is not a token. An adapter
that reads a single-valued cookie, for a strict integer for instance, does not percent-decode it either; cookie arrays
and objects, one cookie for each item or property, keep the `form` style's percent-encoding.

An adapter converts a parameter's text by the schema's type before the model validates it, and accepts fewer
spellings than FastAPI does for a parameter it reads itself: integers and numbers as JSON writes them, so `5`, `-5`,
`2.5`, and `1e3` but not `05`, `+1`, or `1_000`, and booleans only as `true` and `false`. Turning on
`--strict-types int float bool` therefore narrows what those parameters accept. A repeated single value is taken as
FastAPI takes it, by adapters too: the last query value, cookie, form field, and object member, and the first header.

Header values are ASCII, as RFC 9110 writes header text and as the generated client sends them. A request that sends a
header parameter of the operation with a byte outside ASCII, in any of its occurrences, answers `400 {"detail":
"Invalid request"}`, whether FastAPI or an adapter reads it: FastAPI alone would read it as Latin-1. A header with JSON
`content` is ASCII JSON text too, whose escapes such as `\u00e9` stand for other characters. The check covers the
operation's header parameters, not the headers of your own dependencies; a security scheme's credential that is not
ASCII presents no credential instead, as [Security](#security) describes.

Cookie values are ASCII too, the cookie octets of RFC 6265, which is how the generated client sends them. A request
that sends a cookie the operation reads with a byte outside ASCII in its value answers the same `400`, whether
FastAPI or an adapter reads it; other cookies of the request are not read, so they may hold anything. An array or
object cookie keeps the `form` style's percent-encoding of UTF-8 text.

A parameter with JSON `content`, like a JSON part of a multipart form, is parsed by its model's
`TypeAdapter.validate_json`, as a JSON body is, so pydantic's JSON rules apply: a number is read as a float first, so
a `Decimal` field gets the float's value (`0.1000000000000000000000000001` becomes `Decimal("0.1")`) and `NaN` and
`Infinity` reach a `float` field; an object that repeats a member keeps the last value; and text that is not JSON, or
JSON past pydantic's limits such as an integer of thousands of digits or deep nesting, answers `422` with
`json_invalid`.

A strict bytes type (`--strict-types bytes` with `format: byte` and `--type-mappings string+byte=binary`) cannot be a
path, query, header, or cookie parameter, since a parameter carries text: generation stops with an error that names it.
A path, query, header, or cookie parameter whose schema mixes scalar kinds keeps every member when one of them is a
string, such as `int | str` for `type: [integer, string]`. Without a string member, such as `type: [integer, boolean]`,
and for an enum whose values mix kinds, such as `enum: [1, a]`, generation stops with
`A parameter value needs one unambiguous scalar kind`.

A header parameter, response header, or part header whose name is not an RFC 9110 token, such as `X Sp` or `X-Näme`,
stops generation with an error, on the server and the client alike, since no HTTP client or server can send it.

### Responses

A service method returns the value of its primary response, which FastAPI validates and serializes with the route's
`response_model` when the response is JSON (`by_alias=True`, `exclude_unset=True`). Without a
[`--server-primary-responses`](cli-reference/target-generation-options.md#server-primary-responses) entry, the
primary response is `200` when the operation declares it, or else its lowest success status, or else its `2XX` or
else its `default` response, sent as `200`, or else its lowest status. An entry's `status_code` takes the response
that declares it exactly, by its range such as `2XX`, or as `default`. An operation that declares only other ranges,
such as `4XX`, has no primary response: a bare value, `None` included, answers `500` with a `ResponseValidationError`,
so its method returns an `HTTPResult` or a `Response`. A bare value is sent with the `media_type` its entry names,
such as `text/plain` of a response that also declares JSON, and validated and serialized with that media type's
model; without a `media_type`, it takes the response's default media type.

A `text/*` response labels text it encodes with the charset it encodes it in: the one its media type declares, or
else `utf-8`. Bytes a method returns for a `text/*` response are sent as they are, with the media type the document
declares, so they carry a charset only when the document declares one. A text response's model writes the value as its
JSON text does, so an `Enum` member is sent as its value.

An `HTTPResult(status_code, body, headers)` sends another status or extra headers. The package validates and
serializes its body with the model and default media type of the response that declares the status: exactly, by its
range such as `2XX`, or as `default`. A status that no response declares is sent unchecked, its body encoded as JSON
without validation, and without a body as an empty response. A Starlette `Response` is sent as it is, for anything
else, such as another media type or repeated headers. A response leaves out the fields its model leaves unset, so a
`pydantic_v2.dataclass` sends `null` only for a field set to `None`, and a field holding `MISSING` not at all. The
headers of an `HTTPResult` must be ASCII header text under token names, else the result fails as one its response
model rejects; a Starlette `Response` sends its headers unchecked.

A success (`2XX`) response that declares content always sends content. `None`, as a bare value or as an `HTTPResult`
without a body, goes through the response's model like any other value, as FastAPI's `response_model` takes it: a
response whose default media type is JSON and whose model type accepts `null`, as for the request bodies above, sends
the JSON body `null`, and any other one answers `500` with a `ResponseValidationError`. This holds for a status the
response declares exactly, by a range such as `2XX`, or as `default`. Any other status sends `None` as `null` under a
JSON response whose model accepts `null`, and otherwise as an empty response without a `Content-Type`, such as
`HTTPResult(404)` for a declared `404`, so the client raises the status error with an empty body. A status that no
response declares, or whose response declares no content, sends `None` as an empty response too, as a HEAD operation
and the statuses `1XX`, `204`, `205`, and `304` always do.

### Registration

`create_app` and `build_router` look every method up when they register the routes; any object with the right
methods works, and type checkers check it where you pass it. Registration stops with an error for what would
otherwise go wrong without one: a missing method (`AttributeError`), a coroutine function for an operation in the
`sync` handler mode or a plain method for one in the `async` mode, a secured operation without a callable
`authorize`, and an `operation_dependencies` entry that is not a sequence of `Depends(...)` (`TypeError`) or that
names no method of the router (`ValueError`). It also binds the keyword arguments each route passes to its method's
signature, as a call would, and stops with a `TypeError` that names the class, the method, and the argument when they
do not fit; a wider signature, with defaults or `**kwargs`, fits. Type checkers check the types of the arguments and
results. A stub's `NotImplementedError` answers `500`, as any other exception does.

A method's docstring names its route, such as `Handle GET /pets/{petId}.`, or, with `--use-schema-description`, the
operation's summary and description, formatted as model docstrings are, on one line with
`--use-single-line-docstring`. The generated `server/README.md` lists the operations of each service and shows how to
connect an `authorize` callback and your own `FastAPI` application.

### Security

`security.py` declares one FastAPI dependency for each security scheme the selected operations use: FastAPI's
`APIKeyQuery` for an API key in the query, and the runtime's subclasses of FastAPI's `APIKeyHeader`, `APIKeyCookie`,
`HTTPBearer`, `HTTPDigest`, `HTTPBasic`, `OAuth2` with the declared flows, and `OpenIdConnect` for the other schemes,
each with `auto_error=False`. A scheme no FastAPI class reads, such as `mutualTLS`, is a function
that returns `None`; replace it, or any other scheme, with `app.dependency_overrides[security.<scheme>]`. The
credentials are what the dependencies return: a string for an API key, the token of an `Authorization: Bearer`
header for OAuth2 and OpenID Connect, as `OAuth2PasswordBearer` reads it, `HTTPBasicCredentials`, or
`HTTPAuthorizationCredentials`. Each HTTP, OAuth2, and OpenID Connect dependency presents no credential for an
`Authorization` header of another scheme, so a Basic header satisfies no OAuth2 requirement, and the HTTP Basic one
presents none for a malformed Basic header either, so another requirement set can still admit the request. The HTTP
Basic one reads the user name and password as UTF-8, the charset of RFC 7617 that the generated client encodes them
in, where FastAPI's `HTTPBasic` reads ASCII only; Base64 that is not valid, or that does not decode to UTF-8 text with
a `:`, is a malformed Basic header. A credential in a header or a cookie is ASCII, as header text and cookie octets
are: an API key, a bearer token, or Digest credentials with a byte outside ASCII present no credential either, so the
request answers `401` unless another requirement set admits it.

`create_app` and `build_router` of a package with secured operations take an
`authorize(requirement_sets, credentials)` callback, which may be a coroutine function. Each secured operation calls
it once with its security requirement sets whose every scheme presented a credential, in declaration order, and the
credentials by scheme name; the handler receives the principal it returns as the keyword argument
`principal: PrincipalT_contra`, and it rejects a request by raising `HTTPException`. A request that presents no
complete requirement set answers `401`, unless the operation also accepts no credentials, in which case the handler
receives `None`, typed `PrincipalT_contra | None`. The `401` carries a `WWW-Authenticate` challenge for each kind of
scheme the operation accepts, such as `APIKey, Bearer, Basic charset="UTF-8"`: the Basic challenge names UTF-8, the
charset RFC 7617 lets a server ask for, in which the server reads Basic credentials.

A service Protocol with secured operations is generic, `PetsService(Protocol[PrincipalT_contra])`, so
`create_app(pets=..., authorize=...)` ties the principal type of the services to the return type of `authorize`. The
package exports the callback types `Authorize` and `AsyncAuthorize`, `Callable[[RequirementSets, Credentials], P]` and
the same returning `Awaitable[P]`, with `RequirementSets`, a tuple of requirement sets, each a tuple of
`(scheme name, scopes)` pairs, and `Credentials`, `Mapping[str, object]`. FastAPI's document lists each scheme of an
operation as a separate alternative, since FastAPI cannot document a requirement that combines several schemes.

### Served OpenAPI document

`create_app` serves the source document, not one FastAPI builds: generation writes the part of it the selected
paths use into `server/_generated/openapi.json`, and the application reads it on the first request for
`/openapi.json` and keeps it. The file is package data: Hatchling, uv_build, poetry-core, pdm-backend, and
flit_core include it in a distribution by default, while setuptools needs it in `package-data` or `MANIFEST.in`; a
distribution without it answers the document's first request with an error that says so. The document keeps the
source's OpenAPI version, `info`, `servers`, `tags`, security schemes, webhooks, and the selected paths with all
their operations as they are declared, callbacks included; the callbacks and webhooks are documentation only, with
no routes or service methods.

Components stay when something kept references them, and so do the `allOf` subtypes of a kept discriminator base.
What a reference names in another loaded document, or in a path that is left out, joins the components of the
kind the reference's position holds, under its own name or a numbered one when the name is taken; an OpenAPI 3.0
path item, or a media type before 3.2, has no component kind and is copied in place. Since the document publishes
what it references, a server generation reads a local file only inside the input document's directory, after `..`
and symbolic links resolve, and none for a document read from a URL: it fails on any other local file reference
before reading the file, with or without `--allow-remote-refs`. References are rewritten
relative to the document, so a schema's `$id` is left out; a reference resolves as the models resolve it,
through `$id`, `$anchor`, and `$dynamicAnchor`. A reference that names nothing the generation loaded stays as it
is, with a warning. A link whose `operationRef` names a path that is left out is left out, and so is a value without
a JSON form: a YAML `!!binary` value, NaN or infinity, or a YAML alias that contains itself. Each of them is reported
as a `DocumentationAnnotationWarning`.

FastAPI's `/docs` and `/redoc` show the document, and behind a root path FastAPI adds that path as the first
server, as it does for its own document. `create_app`'s `prefix` leads every path, and the references and link
`operationRef`s into the paths follow them. The description settings you pass to `create_app`, `title`, `version`,
`summary`, `description`, `terms_of_service`, `contact`, `license_info`, `servers`, `openapi_tags`, and
`openapi_external_docs`, replace the document's, as they do in FastAPI's own; one you leave unset or empty keeps
the document's. The document is documentation only: the generated models are what the server validates with, and
routes added to the application later do not appear in it.

`create_app(..., source_openapi=False)` serves FastAPI's own document instead, built from the routes and the
models they declare. It describes what FastAPI derives: a parameter, header, or body that only an adapter reads
does not appear in it. An application of your own that includes `build_router(...)` serves FastAPI's document
too, unless it calls `serve_source_openapi(app, prefix=..., metadata=...)`, imported from the generated package,
with the prefix the router is included under and the description settings to replace.

A path placeholder that is no ASCII identifier or is a keyword, that repeats, or whose name an argument of the
endpoint already takes, such as `{request}`, is registered under a name of the route's own, such as `{dcg_p0}` for
`{item-id}`, because Starlette matches a placeholder by an identifier. FastAPI's document shows that name for the
placeholder and its parameter, and so do `request.path_params`, `url_path_for`, and the route path in FastAPI's log
messages. The `loc` of a validation error does not: it names the parameter as the source document does.

### Production settings

The application keeps FastAPI's defaults for its documentation endpoints and for the shape of its error
responses, with one difference: a request that fails validation answers `422` with FastAPI's `{"detail": [...]}`
records without their `input` and `ctx`, and without pydantic's `url`, which FastAPI already leaves out: the
response carries each record's `type`, `loc`, and `msg`, so it does not return the rejected value as such. `loc`
and `msg` are still pydantic's and can hold text the client chose: a key of a mapping or an unexpected field in
`loc`, a discriminator tag in `msg`, and whatever a validator of your own puts in its error message. Parameters and
bodies that adapters read answer with the same three keys, and in the same response: when parameters that FastAPI
reads and parameters that an adapter reads both fail, the `422` carries the records of all of them, ordered as FastAPI
orders its own, by location (path, query, header, cookie, then the body), FastAPI's records of a location before the
adapter's.

`loc` names what the request carries, not the method argument it becomes: a parameter by its location and its name
in the source document, such as `["path", "item-id"]`, `["query", "page[size]"]`, or `["header", "X-Trace-Id"]`,
and a body member by the name the model reads it under, its alias when it has one. That holds whatever
`--snake-case-field`, `--aliases`, or `--server-parameter-names` call the argument, and for a path placeholder the
route registers under a name of its own: the route puts the source name back into FastAPI's records before any
exception handler receives them, so FastAPI's default handler and a handler of your own see it too.

- `create_app` registers the handler, `validation_error_handler`, through FastAPI's `exception_handlers`. Pass
  your own `exception_handlers` to send other error bodies, for example ones without `loc` and `msg`; an entry
  for `RequestValidationError` replaces the package's.
- An application of your own that includes `build_router(...)` keeps FastAPI's default records, with `input` and
  `ctx`, unless you register the handler: `app.add_exception_handler(RequestValidationError,
  validation_error_handler)`, imported from the generated package.
- Other errors are FastAPI's: `404` and `405` bodies, and an opaque `500` for an exception in a service method or a
  result that fails its response model. That error goes to the server log with the values it rejected. Inputs that
  adapters read also answer `400 {"detail": "Invalid request"}` and `415 {"detail": "Unsupported media type"}`, and
  so does a header parameter, or a cookie the operation reads, whose value is not ASCII.
- FastAPI's own document (`source_openapi=False`) describes validation errors with FastAPI's `ValidationError`
  schema, in which `loc`, `msg`, and `type` are required and `input` and `ctx` are optional, so these bodies
  conform to it; the source document describes the responses the source declares.
- `create_app(..., docs_url=None, redoc_url=None, openapi_url=None)` removes `/docs`, `/redoc`, and
  `/openapi.json`.
- The `server` response header is the ASGI server's, not the application's; uvicorn leaves it out with
  `--no-server-header`.

### Templates

The server templates come from [`--custom-template-dir`](cli-reference/template-customization.md#custom-template-dir),
as model templates do: the files of its `fastapi` directory replace the builtin roles of the same name:
`facade.jinja2` (the package initializers), `application.jinja2`, `router.jinja2` (the routes module or each router
module), `services.jinja2`, `contract.jinja2` (`_generated/contract.py`), `security.jinja2`, `openapi.jinja2`
(`_generated/openapi.py`), `main.jinja2`, `readme.jinja2`, and `implementation.jinja2` and `authorize.jinja2`, the
stubs of the `services` modules generation writes once. A role the directory does not hold,
or a custom template directory without a `fastapi` directory, keeps its builtin template. The builtin templates are
in the `_fastapi/templates` directory of the installed package; copy one to start from it. An override may include
or import the other builtin templates.

!!! warning "Overrides are not checked against the builtin roles"

    A file of the `fastapi` directory that is not one of these role names is ignored without a warning, so a
    misspelled or renamed role keeps its builtin template. A value that an override names and the builtin no longer
    provides, such as one that an older copy of a builtin template uses, prints as an empty string and iterates as
    nothing, as Jinja's default `Undefined` does; the values a role receives can change while server generation is
    experimental. Generation can then succeed and write a package that fails when it is imported. Reading an attribute
    of such a value, or calling it, fails the render instead, which stops the run with an `Error` that names the
    template. After each upgrade, compare your overrides with the
    current builtin templates, and in CI import the generated package, or run `datamodel-codegen --check` and your
    tests.

```text
templates/
├── fastapi/
│   └── services.jinja2
└── pydantic_v2/
    └── BaseModel.jinja2
```

Each role receives the values its builtin template uses and, as custom model templates do, the `#all#` entry of
[`--extra-template-data`](cli-reference/template-customization.md#extra-template-data); the role's own values take
precedence over the extra data:

```json
{"#all#": {"team": "the platform team"}}
```

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-server.templates.command -->
<!-- fmt: off -->

```bash
datamodel-codegen \
  --input openapi.yaml \
  --input-file-type openapi \
  --openapi-scopes schemas api \
  --output-model-type pydantic_v2.BaseModel \
  --preset standard-py312-20261015 \
  --output app/models.py \
  --generate-server fastapi \
  --server-output app/server \
  --server-package app.server \
  --server-model-package app.models \
  --custom-template-dir templates \
  --extra-template-data extra.json
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-server.templates.command -->

The templates write every module, class, function, signature, and call; they receive records of names, type
annotations, and the values of the runtime plans. Each role receives these top-level values, where `imports` is the
module's import block:

| Role | Values |
| --- | --- |
| `application.jinja2` | `imports`, `exports`, `final`, `options`, `routes`, `info`, `build_router`, `build`, `services`, `settings`, `create_app`, `arguments`, `fastapi`, `error_handlers`, `serve_source_openapi` |
| `authorize.jinja2` | `imports`, `package`, `entrypoint`, `requirement_sets`, `credentials` |
| `contract.jinja2` | `imports`, `typed_dict`, `dependencies`, `plans`, `final`, `dataclass`, `parameter_adapter`, `body_adapter`, `operation_responses` |
| `facade.jinja2` | `module`, `docstring`, `imports`, `exports` |
| `implementation.jinja2` | `imports`, `protocol`, `services`, `entrypoint`, `name`, `base`, `methods`, `protocol_methods` |
| `main.jinja2` | `imports`, `app`, `services`, `implementations`, `missing`, `table`, `create_app`, `arguments` |
| `openapi.jinja2` | none |
| `readme.jinja2` | `title`, `package`, `model_package`, `backend`, `operations`, `services`, `services_package`, `owned`, `app`, `top_level`, `arguments`, `fakes`, `dependencies`, `schemes`, `forms`, `raw_request` |
| `router.jinja2` | `imports`, `docstring`, `routes`, `api_router`, `wiring`, `final`, `literal`, `templated`, `builder`, `group`, `build`, `services`, `settings` |
| `security.jinja2` | `imports`, `schemes`, `exports` |
| `services.jinja2` | `imports`, `typevar`, `abstract`, `protocol_type`, `protocols` |

`router.jinja2` receives one `route` for each operation, with its local names (`adder`, `router`, `wiring`,
`service`, `handler`), its `lookup` of the service method, whose `keywords` name the arguments the route passes for
the startup check, which an override without them leaves out, its `principal` dependency or none, its `endpoint` with
the endpoint's `parameters` (`name`, `annotation`, `default`) and, for an operation with adapter parameters, the
`accepted` call that the endpoint passes its `record` of them through before it calls the method, the service method
`call` with its `arguments`, and its `registration`, whose `keywords` hold the optional `add_api_route` arguments. An
override that leaves the `accepted` call out still answers `422` when only adapter parameters are rejected, as long as
it reads a value of the record before it calls the method, as the builtin template's arguments do. A builtin template writes each
parameter, argument, and route entry on its own line, and leaves the type annotations and plan values on one line for
the formatter.

A template that does not parse or render stops the run with an `Error` that names the file in the custom
template directory and, when Jinja knows it, the line. Generation also reads the model templates of the same
directory, so the model templates must keep the class and field names, as the [requirements](#requirements) describe.

### Errors and warnings

The command line prints failures to stderr and exits with 2. Most start with `Error: `, followed by the message; an
invalid JSON option prints `Invalid JSON for --server-handler-modes: ...` or, for a value its schema rejects,
`Invalid --server-handler-modes: ...`, naming the option. Target errors combine their messages in order, without
codes, severity or stage labels. Model generation errors keep their messages, including the class-name hint and input
encoding context. Unexpected exceptions print a traceback. Configuration, input, model, binding, planning, and
template errors stop the run before publication.

Warnings are Python `UserWarning` subclasses from `datamodel_code_generator`: `DocumentationAnnotationWarning` reports
a source value the served document cannot carry, and `LeftoverFilesWarning` names the `.py` files under the output
that the generation left in place and does not generate, and points code of your own at `services`. Each message starts with the output path, spelled relative
to the working directory when it lies inside it, so every generated package reports its own files. They respect
`--disable-warnings` and Python warning filters, and are not returned as diagnostic records.

---

# Python Client Generation

Source: https://datamodel-code-generator.koxudaxi.dev/python-client/

!!! warning "Experimental"

    HTTPX2 client generation is experimental. Its options, generated package, and template values may change. See
    [Experimental Features](experimental.md).

`--generate-client httpx2` turns one OpenAPI document into the models and a Python client package in the same run.
The package has a `Client` and an `AsyncClient`, with a *resource* for each tag and a typed method for each
operation, such as `client.pets.get_pet(pet_id=1)`. It sends requests with
[HTTPX2](https://github.com/pydantic/httpx2), the `httpx2` package on PyPI, and handles what the document declares:
servers, parameters, bodies, responses, errors, and authentication.

```text
openapi.yaml ──► datamodel-codegen ──► app/models.py, app/client/    generated, overwritten on every run
                                            ▲
                                            │ import, call client.<resource>.<operation>(...)
                                       your code and tests    yours, never touched
```

This page covers a tutorial, how-tos for calling operations, configuring the client, authentication, errors, and
tests, and the generation settings. Two more pages go further: [Python Client Protocol Helpers](python-client-helpers.md)
for pagination, polling, streams, uploads, caching, and webhooks, and the
[Python Client Reference](python-client-reference.md) for the precise rules. For the server of the same document, see
[FastAPI Server Generation](fastapi-server.md); for every option with examples, see
[CLI Reference: Target Generation Options](cli-reference/target-generation-options.md).

## Quick start

This tutorial generates a client for the pet store of the [server quick start](fastapi-server.md#quick-start) and
calls it. Start in an empty directory of a uv project, with `datamodel-codegen`
[installed](getting-started.md#installation). Client generation needs Python 3.11 or later; the preset below targets
Python 3.12.

### 1. Describe the API

Save the document as `openapi.yaml`. It is the server quick start's document:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.openapi -->
<details>
<summary>openapi.yaml</summary>

<!-- fmt: off -->

```yaml
openapi: 3.1.0
info:
  title: Pets
  version: "1.0"
servers:
  - url: http://localhost:8000
paths:
  /pets:
    get:
      operationId: listPets
      tags: [pets]
      parameters:
        - name: limit
          in: query
          schema: {type: integer, minimum: 1, maximum: 100, default: 20}
      responses:
        "200":
          description: The pets.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pets"}
    post:
      operationId: createPet
      tags: [pets]
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: "#/components/schemas/NewPet"}
      responses:
        "201":
          description: Created.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
  /pets/{petId}:
    get:
      operationId: getPet
      tags: [pets]
      parameters:
        - name: petId
          in: path
          required: true
          schema: {type: integer}
      responses:
        "200":
          description: The pet.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
        "404":
          description: No pet has this ID.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Error"}
components:
  schemas:
    NewPet:
      type: object
      required: [name]
      properties:
        name: {type: string}
        tag: {type: string}
    Pet:
      type: object
      required: [id, name]
      properties:
        id: {type: integer}
        name: {type: string}
        tag: {type: string}
    Pets:
      type: array
      items: {$ref: "#/components/schemas/Pet"}
    Error:
      type: object
      required: [message]
      properties:
        message: {type: string}
```

<!-- fmt: on -->
</details>
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.openapi -->

The client sends to the document's `servers`, here `http://localhost:8000`. Each operation becomes a method named after
its `operationId`, on the resource of its first tag, `pets`.

### 2. Generate the client

Everything goes into one application package, `app`, as in the [server quick start](fastapi-server.md#2-generate-the-server):
create it with an empty `app/__init__.py`.

```bash
mkdir -p app && touch app/__init__.py
```

Put the settings in `pyproject.toml` and run `datamodel-codegen` without arguments, or pass them as options:

=== "pyproject.toml"

    <!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.pyproject -->
    <!-- fmt: off -->

    ```toml
    [tool.datamodel-codegen]
    input = "openapi.yaml"
    input-file-type = "openapi"
    openapi-scopes = ["schemas", "api"]
    output-model-type = "pydantic_v2.BaseModel"
    preset = "standard-py312-20261015"
    output = "app/models.py"
    generate-client = "httpx2"
    client-output = "app/client"
    client-package = "app.client"
    client-model-package = "app.models"
    ```

    <!-- fmt: on -->

    <!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.pyproject -->

=== "Command line"

    <!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.command -->
    <!-- fmt: off -->

    ```bash
    datamodel-codegen \
      --input openapi.yaml \
      --input-file-type openapi \
      --openapi-scopes schemas api \
      --output-model-type pydantic_v2.BaseModel \
      --preset standard-py312-20261015 \
      --output app/models.py \
      --generate-client httpx2 \
      --client-output app/client \
      --client-package app.client \
      --client-model-package app.models
    ```

    <!-- fmt: on -->

    <!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.command -->

The [preset](presets.md) supplies the model options, as in the model [quick start](getting-started.md), and
`--openapi-scopes schemas api` makes models for the parameters, bodies, and responses of the operations too.

Generation ends by printing the command that adds the package's runtime dependencies to your project, and the next
steps: a call of the first operation in a client's context, and the README of the package:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.notice -->
<!-- fmt: off -->

```text
Add the runtime dependencies of app.client to your project:
  uv add "httpx2>=2.13.0" "typing-extensions>=4.16" "pydantic>=2.14.0"
Next steps: call the API with the client:
  from app.client import Client

  with Client(base_url=...) as client:
      client.pets.list_pets(...)
See app/client/README.md.
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.notice -->

Run the `uv add` command. `httpx2` is [HTTPX2](https://github.com/pydantic/httpx2), the HTTP library the client sends with; it is not
the `datamodel-code-generator[httpx2]` extra, which only fetches remote schemas while generating. The command names
only the minimum version of each package, so uv adds the latest release, and it grows with what the document uses,
such as `httpx2[ws]` for WebSocket helpers or `cryptography` for public-key webhook signatures.

The run wrote the models and the `app.client` package:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.tree -->
<!-- fmt: off -->

```text
app/
├── __init__.py
├── client/
│   ├── README.md
│   ├── __init__.py
│   ├── _generated/
│   ├── _generated_docs/
│   ├── _runtime/
│   ├── errors.py
│   ├── options.py
│   ├── py.typed
│   ├── resources/
│   │   ├── __init__.py
│   │   └── pets/
│   │       └── __init__.py
│   ├── responses.py
│   └── types/
│       ├── __init__.py
│       └── pets/
│           └── __init__.py
└── models.py
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.tree -->

`app/client/__init__.py` exports `Client` and `AsyncClient`, `resources/` and `types/` hold a package for each resource,
`types/__init__.py` exports `JSONValue`, the type of an argument that takes any JSON value, and `errors.py`,
`options.py`, and `responses.py` are the public modules you import from. `_generated/` and `_runtime/`
hold the plans and the runtime the package imports. `README.md` shows how to call the package and lists the method of
every operation with its signature, and `_generated_docs/runtime.md` is the runtime reference it links to.
Every file here is overwritten on each run, so keep your own code outside `app/client/`.

### 3. Call the API

Start the server of the [server quick start](fastapi-server.md#5-run-it) with `uv run uvicorn app.server.main:app`, or any server
that implements the document at `http://localhost:8000`. Then save `call.py`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.call -->
<!-- fmt: off -->

```python
from app.client import Client
from app.client.errors import NotFoundError
from app.models import NewPet

with Client() as client:
    pet = client.pets.create_pet(body=NewPet(name="Mimi", tag="cat"))
    print(pet)
    for listed in client.pets.list_pets(limit=10).root:
        print(listed.name)
    try:
        client.pets.get_pet(pet_id=99)
    except NotFoundError as error:
        print(error.status_code, error.body)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.call -->

```bash
uv run python call.py
```

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.call-output -->
<!-- fmt: off -->

```text
id=1 name='Mimi' tag='cat'
Mimi
404 message='Pet 99 not found'
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.call-output -->

`Client()` sends to the document's server; `with` closes its connections at the end. Each method takes the
operation's parameters as keyword arguments and its body as `body=`, sends the request, and returns the response
decoded into its model, such as `Pet`. A declared error status raises an exception that carries the decoded error
body, such as `NotFoundError` for the `404` of `get_pet`.

The method of `get_pet`, from `app/client/resources/pets/_sync.py`, shows what a call takes:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.method -->
<!-- fmt: off -->

```python
    def get_pet(
        self,
        *,
        pet_id: int,
        response_media_type: Literal['application/json'] | None = None,
        options: RequestOptions | None = None,
    ) -> GetPetResponse:
        """
        Call GET /pets/{petId}.
        """
        return self._core.execute(
            _operations.OPERATION_2,
            (pet_id,),
            options=options,
            response_media_type=response_media_type,
        ).data
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.method -->

The `petId` path parameter is the argument `pet_id`, since the preset turns on snake-case field names.
`response_media_type` and `options` are on every method: the first picks one of the declared response media types,
and the second takes the [settings of one call](#configure-the-client).

### 4. Use asyncio

`AsyncClient` has the same resources and methods, as coroutines:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.async -->
<!-- fmt: off -->

```python
import asyncio

from app.client import AsyncClient
from app.models import NewPet


async def main() -> None:
    async with AsyncClient() as client:
        pet = await client.pets.create_pet(body=NewPet(name="Rex", tag="dog"))
        print(await client.pets.get_pet(pet_id=pet.id))


asyncio.run(main())
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.async -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.async-output -->
<!-- fmt: off -->

```text
id=2 name='Rex' tag='dog'
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.tutorial.async-output -->

Use `async with` to close it, and await each call.

### Recap

- The OpenAPI document is the source: the models, the resources, and the methods come from it.
- `datamodel-codegen` regenerates every file of `app/models.py` and `app/client/` on each run.
- `Client` and `AsyncClient` send with HTTPX2 to the document's servers; each tag is a resource and each operation a
  method with keyword arguments.
- A method returns the decoded model and raises a typed exception for an error status.

## Call operations

The how-tos below use a second document, a pet shelter whose operations need a bearer token:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.openapi -->
<details>
<summary>openapi.yaml</summary>

<!-- fmt: off -->

```yaml
openapi: 3.1.0
info:
  title: Pet shelter
  version: "1.0"
servers:
  - url: https://{region}.shelter.example/v1
    variables:
      region: {default: eu, enum: [eu, us]}
security:
  - bearer: []
  - oauth: [pets.read]
paths:
  /pets:
    get:
      operationId: listPets
      tags: [pets]
      parameters:
        - name: limit
          in: query
          schema: {type: integer, minimum: 1, maximum: 100, default: 20}
        - name: tag
          in: query
          schema: {type: string}
      responses:
        "200":
          description: The pets.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pets"}
    post:
      operationId: createPet
      tags: [pets]
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: "#/components/schemas/NewPet"}
      responses:
        "201":
          description: Created.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
  /pets/{petId}:
    get:
      operationId: getPet
      tags: [pets]
      parameters:
        - name: petId
          in: path
          required: true
          schema: {type: integer}
      responses:
        "200":
          description: The pet.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
        "404":
          description: No pet has this ID.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Error"}
  /pets/{petId}/adoption:
    post:
      operationId: adoptPet
      tags: [adoptions]
      parameters:
        - name: petId
          in: path
          required: true
          schema: {type: integer}
      responses:
        "200":
          description: Adopted.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Pet"}
        "409":
          description: The pet is already adopted.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Error"}
  /health:
    get:
      operationId: getHealth
      security: []
      responses:
        "200":
          description: The service is up.
          content:
            application/json:
              schema: {$ref: "#/components/schemas/Health"}
components:
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
    oauth:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.shelter.example/token
          scopes:
            pets.read: Read pets.
  schemas:
    NewPet:
      type: object
      required: [name]
      properties:
        name: {type: string}
        tag: {type: string}
    Pet:
      type: object
      required: [id, name]
      properties:
        id: {type: integer}
        name: {type: string}
        tag: {type: string}
    Pets:
      type: array
      items: {$ref: "#/components/schemas/Pet"}
    Health:
      type: object
      required: [status]
      properties:
        status: {type: string}
    Error:
      type: object
      required: [message]
      properties:
        message: {type: string}
```

<!-- fmt: on -->
</details>
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.openapi -->

Its client adds two settings to the quick start's table, explained in [Request bodies](#request-bodies) and
[Responses](#responses):

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.pyproject -->
<!-- fmt: off -->

```toml
[tool.datamodel-codegen]
client-body-arguments = "both"
client-operations = '{"/paths/~1pets/get": {"runtime": {"request_id_header": "X-Request-Id"}}}'
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.pyproject -->

The shelter is not a real service, so each example passes `http_client=http_client()`, an HTTPX2 client from
`fake.py` whose transport prints every request and answers from memory. Leave out `http_client=` to call a real
server; [Test code that uses the client](#test-code-that-uses-the-client) shows the technique.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.fake -->
<details>
<summary>fake.py</summary>

<!-- fmt: off -->

```python
"""A stand-in for the shelter API: an HTTPX2 client whose transport prints each request and answers from memory."""

import json

import httpx2

PETS = {"1": {"id": 1, "name": "Mimi", "tag": "cat"}, "2": {"id": 2, "name": "Rex", "tag": "dog"}}
SHOWN = ("authorization", "content-type", "x-app", "x-trace", "x-signature")
health_checks: list[int] = []


def answer(request: httpx2.Request) -> httpx2.Response:
    path = request.url.path.removeprefix("/v1")
    match request.method, path.split("/")[1:]:
        case "POST", ["token"]:
            return httpx2.Response(200, json={"access_token": "issued-1", "token_type": "Bearer", "expires_in": 3600})
        case "GET", ["pets"]:
            return httpx2.Response(200, json=list(PETS.values()), headers={"X-Request-Id": "req-7"})
        case "POST", ["pets"]:
            return httpx2.Response(201, json={"id": 3, **json.loads(request.content)})
        case "GET", ["pets", "1" | "2"]:
            return httpx2.Response(200, json=PETS[path.split("/")[2]])
        case "POST", ["pets", "1", "adoption"]:
            return httpx2.Response(409, json={"message": "Mimi is already adopted"})
        case "GET", ["health"]:
            health_checks.append(len(health_checks))
            return httpx2.Response(503 if len(health_checks) < 3 else 200, json={"status": "up"})
        case _:
            return httpx2.Response(404, json={"message": f"{path} not found"})


def handle(request: httpx2.Request) -> httpx2.Response:
    if request.url.host == "offline.example":
        raise httpx2.ConnectError("connection refused", request=request)
    headers = "".join(f" {name}: {value}" for name, value in request.headers.items() if name in SHOWN)
    print(f"> {request.method} {request.url}{headers} {request.content.decode()}".rstrip())
    return answer(request)


def http_client() -> httpx2.Client:
    return httpx2.Client(transport=httpx2.MockTransport(handle))
```

<!-- fmt: on -->
</details>
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.fake -->

### Arguments and naming

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.calls -->
<!-- fmt: off -->

```python
from app.client import Client
from app.client.options import UNSET
from fake import http_client
from app.models import NewPet

with Client(bearer="s3cret", http_client=http_client()) as client:
    print(client.pets.get_pet(pet_id=1))

    client.pets.list_pets()
    client.pets.list_pets(limit=5, tag="cat")
    client.pets.list_pets(tag=UNSET)

    print(client.pets.create_pet(body=NewPet(name="Kiki")))
    print(client.pets.create_pet(name="Kiki", tag="bird"))
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.calls -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.calls-output -->
<!-- fmt: off -->

```text
> GET https://eu.shelter.example/v1/pets/1 authorization: Bearer s3cret
id=1 name='Mimi' tag='cat'
> GET https://eu.shelter.example/v1/pets?limit=20 authorization: Bearer s3cret
> GET https://eu.shelter.example/v1/pets?limit=5&tag=cat authorization: Bearer s3cret
> GET https://eu.shelter.example/v1/pets?limit=20 authorization: Bearer s3cret
> POST https://eu.shelter.example/v1/pets content-type: application/json authorization: Bearer s3cret {"name":"Kiki"}
id=3 name='Kiki' tag=None
> POST https://eu.shelter.example/v1/pets content-type: application/json authorization: Bearer s3cret {"name":"Kiki","tag":"bird"}
id=3 name='Kiki' tag='bird'
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.calls-output -->

Every argument is a keyword. Methods, resource namespaces, and modules are named in snake case, and classes in
PascalCase, whatever the model naming options say: a method after its operationId, or after its method and path
without one, such as `get_pets_by_pet_id` for `GET /pets/{petId}`, and a resource after its operation's first tag.
Operations without a tag join the resource `default`, as `get_health` does here: `client.default.get_health()`.

Arguments are named after their wire names as model fields are, so `--snake-case-field`, which the quick start's
preset turns on, `--aliases`, `--special-field-name-prefix`, `--remove-special-field-name-prefix`, and
`--original-field-name-delimiter` apply to them. Without the preset, a `petId` parameter is the argument `petId` and an
`X-Request-Id` header `X_Request_Id`; pass `--snake-case-field` (`snake-case-field = true`) for snake_case arguments
such as `pet_id`. It renames the model fields too, behind their aliases. A derived name that its namespace already
holds takes the model's suffix, such as `get_pet_1` for a second `get_pet`, `id_1` for a query `id` beside a path `id`,
or `options_1` for a parameter named after a call option. The model's `--naming-strategy` rules apply to these names
too, with the resource as the parent of a method and the method as the parent of an argument, and its
`--duplicate-name-suffix` (the `model` entry, or `default`) tells apart a derived class name, such as an operation's
PascalCase name, as it does a model class; method and argument names keep the number. An explicit name, a `name`,
`parameter_names`, `body_field_names` or `--client-resource-names` entry or an `--aliases` entry, must be a new Python
identifier and is never renamed.

### Request bodies

A body is the argument `body`, the model of its schema, such as `body=NewPet(name="Kiki")`; `media_type` picks one of
the declared request media types when the operation declares several. With
[`--client-body-arguments both`](cli-reference/target-generation-options.md#client-body-arguments), as in this
project, a call may give the fields of an object body as keyword arguments instead, as the last call above does with
`name="Kiki", tag="bird"`; the client builds the model from them and sends only the fields given. A call gives the body
or its fields, never both. See [Body field arguments](python-client-reference.md#body-field-arguments) for which
bodies take fields and how they are named.

A `$ref` beside only annotations, such as `description` or `x-` extensions, takes the type and constraints of the
referenced component, as a bare `$ref` does, for a body and for a parameter. The client checks a plain value the
component's constraints refuse before sending: a call raises a `DecodeError` with the reason `unencodable` instead of
the server answering 422.

A `format: binary` string is raw bytes, which only a whole body, such as `application/octet-stream`, `image/png` or
`text/csv`, or a file part of a multipart form can carry; a `text/*` body whose model types its whole value as one
binary string travels as its raw bytes, without a charset decoding or base64, as an `application/octet-stream` one
does; the method takes such a body or part as `bytes`. The model type decides: the schema is such a string, or reaches
one through a `$ref`, a single `allOf`, `anyOf` or `oneOf` branch, or `allOf` branches that merge into one, such as
`allOf: [{type: string}, {format: binary}]`, also beside a `null`, a length limit or other binary strings. When the models
constrain those bytes, such as `maxLength: 16` as Pydantic's `conbytes(max_length=16)`, the client checks them by the
model: a `bytes` body the model refuses raises a `DecodeError` with the reason `unencodable` before anything is sent,
and a response body it refuses one with the reason `invalid_value`; a file, a path or an iterable is sent as it streams,
for the server to check. Models that keep no such constraint, such as dataclasses and TypedDicts, check nothing, and
unconstrained bytes pass without a model call. An `enum` or a `const` of binary strings, also one that leaves out
`type: string`, is text in the models, so the method takes a body of one, also an `application/octet-stream` one, as
its model, such as an `Enum`, and sends its text. Generation stops with an error when
a binary string, at any depth of its schema and through references, `$dynamicRef` and `allOf`, would be sent as text:
inside a JSON or URL-encoded body or response, also one whose model types its whole value as bytes, a `text/*` body
whose schema is an object, an array, or an `anyOf` or `oneOf` with a branch that is not a binary string, a binary body,
such as `application/octet-stream`, whose model types its whole value as bytes only in part, such as
`type: [string, integer]` or an `anyOf` of a binary string and an integer (`bytes | int`), a multipart part that is
not a file, an item of a streamed response, or a parameter or header. The model backends write `bytes` in JSON differently, Pydantic as raw UTF-8 text and the
others as base64, so such a value would not reach a server, such as a generated FastAPI one, intact. The error names the
operation, the media or parameter, and where the schema declares the string:

```text
Error: /components/schemas/Blob/properties/data: The application/json request body of POST /blobs carries a binary
string as text; declare it with format: byte for base64 text, optionally with --type-mappings string+byte=binary to
keep bytes, or send it as a whole binary body or a file part
```

Declare such a value `format: byte`, which every backend sends as the same base64 text: Pydantic models hold it as a
`Base64Str` and the other backends as the base64 `str`. With
[`--type-mappings string+byte=binary`](cli-reference/typing-customization.md#type-mappings) every backend holds the
decoded `bytes` instead (`Base64Bytes` in Pydantic models) and still sends base64. Build a `Base64Bytes` field in
Python from the base64 text, such as `base64.b64encode(data)`, not from the raw bytes: Pydantic decodes raw bytes
leniently, so `b'\xff\x00'` becomes `b''` without an error. A `--type-mappings` entry that maps a format to `binary`,
such as `password=binary`, makes its strings binary too, and one that maps `binary` to another format makes them
text. A string with an OpenAPI 3.1 `contentMediaType` and no `contentEncoding` is a `str` in JSON and
is sent as it is.

### Optional arguments, `UNSET`, and `None`

An optional parameter with a default its schema declares takes that default, such as `limit: int = 20`, and is
always sent. Any other optional argument defaults to `UNSET`, as `tag: str | UNSET = UNSET` does: the request leaves it
out, and passing `UNSET` is the same as leaving the argument out, as the third `list_pets` call above shows.

`UNSET`, exported from `client.options`, is a `typing_extensions.Sentinel` ([PEP 661](https://peps.python.org/pep-0661/)),
not an `Enum` member: it marks an omitted value, distinct from `None`, and is both the default and its own type, as in
`limit: int | UNSET = UNSET`; test for it with `is UNSET`. A type checker must support PEP 661 sentinels to accept these
annotations: mypy 2.4 or later (mypy 2.3 reports `valid-type`), or Pyright and ty, which the generated packages are
checked with in strict mode.

A parameter style has no spelling of null, so `None` for an optional nullable query, header, or cookie parameter is
sent as `UNSET` is: the parameter is left out, which a server reads as absent. Forms cannot write null either, so a
`None` member of an object parameter, of a URL-encoded or multipart form body, and a `FieldPart` whose value is `None`
are left out too. A parameter declared with `content`
sends JSON `null`. A required parameter, including a path parameter, and an array item refuse `None` with a
`DecodeError` whose reason is `unencodable`. [Model codecs](python-client-reference.md#model-codecs) has the full
conversion rules.

`None` for an optional request body whose schema rejects JSON `null` is sent as `UNSET` is: the request has no body
and no `Content-Type`, which a server reads as an absent body, and a `media_type` beside it is refused with a
`ConfigurationError` whose reason is `without_body`. A JSON body whose type admits `null`, such as a nullable schema,
one without a schema, or `Any`, sends `null`. Generation decides this from the type the models give the body, by the
same rule the generated FastAPI server reads a body and sends a response by, so every model backend sends the same
request: an `x-python-type` annotation admits `null` when it writes `None`, `object`, `Any` under any alias, or a
`Literal` with `None`. The media a call names decides, or the default media without one; an operation with several
media and no default leaves `None` out when none of them takes `null`, and otherwise needs `media_type`. A text, form,
or binary body has no `null`, so its `None` is left out.

### Responses

A method returns the decoded body. Each resource also has three *response views*, the same methods returning more:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.responses -->
<!-- fmt: off -->

```python
from app.client import Client
from fake import http_client

with Client(bearer="s3cret", http_client=http_client()) as client:
    response = client.pets.with_response.list_pets(tag="cat")
    info = response.info
    print(len(response.data.root), info.status_code, info.content_type, info.request_id, info.attempt_count)
    print(info.headers.get("x-request-id"), info.headers)

    raw = client.pets.with_raw_response.get_pet(pet_id=99)
    print(raw.info.status_code, raw.json())

    with client.pets.with_streaming_response.list_pets() as streamed:
        body = b"".join(streamed.iter_bytes())
    print(streamed.info.status_code, len(body))
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.responses -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.responses-output -->
<!-- fmt: off -->

```text
> GET https://eu.shelter.example/v1/pets?limit=20&tag=cat authorization: Bearer s3cret
2 200 application/json req-7 1
req-7 HeadersView(<3 headers>)
> GET https://eu.shelter.example/v1/pets/99 authorization: Bearer s3cret
404 {'message': '/pets/99 not found'}
> GET https://eu.shelter.example/v1/pets?limit=20 authorization: Bearer s3cret
200 70
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.responses-output -->

| View | Returns |
|---|---|
| `client.pets.list_pets(...)` | The decoded body, such as `Pets` |
| `client.pets.with_response.list_pets(...)` | A `Response` with the decoded `data` and the `info` of the response |
| `client.pets.with_raw_response.list_pets(...)` | A `RawResponse` with the body read into memory but not decoded; an error status does not raise |
| `client.pets.with_streaming_response.list_pets(...)` | A context manager that sends on entry and yields a `RawResponse` whose body you read as it arrives |

`Response`, `ResponseInfo`, `RawResponse`, `AsyncRawResponse`, and `HeadersView` come from `client.responses`.
`ResponseInfo` describes one completed call:

| Field | Value |
|---|---|
| `status_code` | The final status |
| `headers` | The final response's headers as a `HeadersView`: `get(name)` returns the first value, `get_all(name)` every value, in received order and compared without case; its representation shows no value |
| `content_type` | The response's media type, or `None` |
| `request_id` | The value of the operation's `request_id_header`, here `X-Request-Id`, which a [per-operation setting](#per-operation-settings) declares; otherwise `None` |
| `attempt_count` | How many attempts the call sent, retries included |
| `elapsed` | The seconds the call took, retries and waits included |

A `RawResponse` has `info`, `read()`, `text()`, `json()`, `iter_bytes()`, `iter_raw_bytes()`, `stream_to(path or file)`,
and `raise_for_status()`, which raises the error a typed call would; `AsyncRawResponse` has the same as coroutines and
async iterators. Leave a streaming response's `with` block to release it, also when you stop reading early. The client
and its views also have `request_raw(method, url, ...)`, which sends a request outside the operations and returns a
`RawResponse`.

The text of `ResponseInfo.headers` is what HTTPX2 decodes, with one codec for the whole header set of the response:
ASCII, else UTF-8 when every header is UTF-8, else Latin-1. A declared response header that a typed call reads is ASCII
header text, whatever the codec chose; see [model codecs](python-client-reference.md#model-codecs).

## Configure the client

### Client settings

`Client` and `AsyncClient` take their settings as keywords. `client.with_options(...)` returns a [view](#views) with
some of them replaced, and a method's `options=RequestOptions(...)` replaces them for one call. `RequestOptions`,
`RetryOptions`, `ServerSelection`, `Clock`, and `UNSET` come from `client.options`.

| Keyword | `Client` | `with_options` | `RequestOptions` | Meaning |
|---|---|---|---|---|
| `base_url` | Yes | Yes | Yes | One URL that replaces the document's servers; see [Base URLs and servers](#base-urls-and-servers) |
| `server` | Yes | Yes | Yes | A `ServerSelection` of a declared server and its variables |
| `default_headers`, `default_query` | Yes | Yes | `extra_headers`, `extra_query` | Headers and query fields added to every request; see [Headers and query defaults](#headers-and-query-defaults) |
| `timeout` | Yes | Yes | Yes | The HTTPX2 phase limits; see [Timeouts](#timeouts) |
| `total_timeout` | Yes | Yes | Yes | A budget for the whole call, retries included |
| `max_retries`, `retry` | Yes | Yes | Yes | The retry count and a `RetryOptions`; see [Retries](#retries) |
| `follow_redirects` | Yes | Yes | Yes | Whether HTTPX2 follows redirects; see [Redirects](python-client-reference.md#redirects-and-transport-construction) |
| `auth` | Yes | Yes | Yes | An `httpx2.Auth` that replaces the credentials; see [Authenticate](#authenticate) |
| `idempotency_key` | No | No | Yes | The key of one call; see [idempotency keys](python-client-reference.md#supply-and-retain-an-idempotency-key) |
| Credentials, such as `bearer` | Yes | No | No | One keyword per security scheme; see [Authenticate](#authenticate) |
| `clock` | Yes | No | No | The time, jitter, and wait sources; see [Clocks](python-client-reference.md#clocks-and-retry-jitter) |
| `http_client` | Yes | No | No | An HTTPX2 client of your own; see [Use your own HTTPX2 client](#use-your-own-httpx2-client) |
| `compression` | Yes | Yes | Yes | Only in a package with an operation that accepts gzip; see [Request compression](python-client-reference.md#request-compression) |
| `helper_defaults`, `cache_stores`, `allowed_origins` | Yes | No | No | Only in a package with protocol helpers; see [Helper settings](python-client-helpers.md#helper-settings-on-the-client) |

A setting a call leaves unset inherits from the nearest view, then the client. The example below sets several of them:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.options -->
<!-- fmt: off -->

```python
import httpx2

from app.client import Client
from app.client.options import RequestOptions, ServerSelection
from fake import http_client

with Client(
    bearer="s3cret",
    server=ServerSelection(variables={"region": "us"}),
    default_headers={"X-App": "shelter-cli"},
    timeout=httpx2.Timeout(10, connect=2),
    http_client=http_client(),
) as client:
    client.pets.list_pets()

    traced = client.with_options(default_headers={"X-Trace": "on"}, total_timeout=30)
    traced.pets.list_pets()

    staging = RequestOptions(base_url="https://staging.shelter.example/v1", extra_headers={"X-App": None})
    client.pets.list_pets(options=staging)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.options -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.options-output -->
<!-- fmt: off -->

```text
> GET https://us.shelter.example/v1/pets?limit=20 x-app: shelter-cli authorization: Bearer s3cret
> GET https://us.shelter.example/v1/pets?limit=20 x-app: shelter-cli x-trace: on authorization: Bearer s3cret
> GET https://staging.shelter.example/v1/pets?limit=20 authorization: Bearer s3cret
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.options-output -->

### Base URLs and servers

Each operation sends to its effective OpenAPI `servers`, those of the operation, its path item, or the document. By
default a call uses the first of them with the default of every server variable. A relative server URL resolves
against `--client-server-base-url`, or against the document's own URL when it was read over HTTP or HTTPS. An
operation without servers uses `--client-default-base-url`; without one, generation fails, for a `GET /pets` with
`Error: /paths/~1pets/get: A server of GET /pets does not resolve to an absolute http or https URL`.

`server=ServerSelection(index=, variables=)` picks another declared server by position and supplies its variables, as
the example picks the `us` region of the shelter's server; `base_url=` replaces the servers with one URL, as its last
call does. `Client`, `with_options`, and `RequestOptions` take the same two
keywords, and the nearest one given wins: a call's over its view's, a view's over the client's, so a view's `server`
also replaces the client's `base_url`. Giving both on one of them raises `ConfigurationError` with the reason
`conflicts_with_server`. An index the operation does not declare raises `ConfigurationError` with `out_of_range`, a
variable it does not declare `undeclared`, and a value outside a variable's `enum` `not_allowed`, when the call is
made.

### Headers and query defaults

`default_headers` and `default_query` of the client and its views, and a call's `extra_headers` and `extra_query`, give
each name they list their value over the generated headers and query, the client's first, then the views', the call's
parameters', and the call's extra ones last; None removes that name. Header names compare case-insensitively, query
names exactly. A body's media type ranks above every layer but the call's `extra_headers`: only a call's Content-Type
relabels its body, or with None sends it unlabelled, and a multipart one without `boundary=` keeps the body's boundary.
A header's name is an HTTP token and its value [header text](python-client-reference.md#model-codecs), HTAB, SP, and visible ASCII without
whitespace at either end, or None: for any other, such as a value with a line break, `café`, or a space at its end,
`Client(...)`, `with_options(...)`, and `RequestOptions(...)` raise `ConfigurationError` with the reason
`invalid_value` and the `field_path` `("headers", name)`, so nothing is sent.

### Timeouts

The example above limits each HTTPX2 phase of a request to 10 seconds and connecting to 2, and gives every call of
the `traced` view a budget of 30 seconds, retries and waits included.

| Setting | Effective default | Meaning |
|---|---|---|
| `timeout` | Owned client: connect 5, read/write/pool 600 seconds; injected client: its native timeouts | Native I/O phase limits |
| `total_timeout` | `None` | Optional budget across attempts and retry waits, starting at call entry |
| `clock` | `Clock()`, the system clock | Client only: time, jitter, and wait sources |

Each setting a call leaves None inherits from the nearest `with_options` view, then the client. Where None has a
meaning of its own, UNSET is the default and inherits instead: `timeout=None` clears all four phase limits, and
`total_timeout=None` on a view or a call removes an inherited total budget. A number as `timeout` limits every phase,
and an `httpx2.Timeout` gives each phase its own limit. An injected HTTP client's native timeouts supply the initial
phase settings unless the client is given `timeout`. Durations must be finite and nonnegative; booleans are rejected.
Invalid values raise `ConfigurationError` with the setting's `field_path`. `total_timeout=0` is valid configuration;
starting a call with it raises `APITimeoutError` before preparing or sending a request.

See [Timeouts and cancellation](python-client-reference.md#timeouts-and-cancellation) for the budget across attempts,
cancellation, and streams.

### Retries

A call is sent again after a failure that may pass, such as a connection that could not open or a `503`, as long as the
operation is safe to send again. The waits grow exponentially. This client waits without jitter and through a
[`Clock`](python-client-reference.md#clocks-and-retry-jitter) that records each wait instead of sleeping, so the
example shows them:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.retries -->
<!-- fmt: off -->

```python
from app.client import Client
from app.client.options import Clock, RetryOptions
from fake import http_client

waits: list[float] = []
clock = Clock(monotonic=lambda: sum(waits), sleep=waits.append)

with Client(retry=RetryOptions(jitter="none"), clock=clock, http_client=http_client()) as client:
    response = client.default.with_response.get_health()
    print(response.data, response.info.attempt_count, waits)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.retries -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.retries-output -->
<!-- fmt: off -->

```text
> GET https://eu.shelter.example/v1/health
> GET https://eu.shelter.example/v1/health
> GET https://eu.shelter.example/v1/health
status='up' 3 [0.5, 1.0]
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.retries-output -->

`max_retries` and `retry=RetryOptions(...)` apply on clients, views, and calls. The fields of `RetryOptions` merge
independently; omitted fields inherit, while a status set replaces the inherited set, and `retry=None` inherits the
whole record. Automatic retries require a candidate failure or status, operation safety, replayable input, and enough
time. JSON/model decoding, arbitrary callbacks,
cancellation, and logical deadlines never restart a request.

| Setting | Effective default | Meaning |
|---|---|---|
| `max_retries` | `2` | Retries after the initial attempt; `0` disables retries; a setting of its own, not a `RetryOptions` field |
| `initial_delay`, `max_delay` | `0.5`, `8` seconds | Exponential backoff, with maximum at least the initial delay |
| `jitter` | `"full"` | Uniform delay below the exponential cap; `"none"` uses the cap |
| `statuses` | `{408, 429, 500, 502, 503, 504}` | Replace with an integer set in 400–599; 401/403/407 are forbidden |
| `max_retry_after` | `60` seconds | Positive cap on accepted server delay; `None` removes this cap |
| `respect_retry_after` | `True` | Explicit `False` ignores server delay hints |
| `retry_after_ms_header`, `should_retry_header` | Operation declaration, otherwise `None` | Vendor controls require generated metadata; explicit `None` disables one |
| `retry_on_pool_timeout` | `False` | Avoid amplifying pool contention unless explicitly enabled |

GET, HEAD, OPTIONS, PUT, and DELETE are eligible for retries by default. POST, PATCH, and other methods require an explicit
`retry_safety="idempotent"` declaration or a valid server key contract. A native `ConnectError` (TLS and DNS failures
included), `ConnectTimeout`, or `PoolTimeout` proves the request unsent and can permit otherwise unsafe methods,
unless an earlier attempt of the call, or a response HTTPX2 followed a redirect from, reached the server; every other
failure after the send started may have been sent and is never sent again. `retry_safety="never"` prohibits every
resend, including an unsent request.

See [Retries and operation contracts](python-client-reference.md#retries-and-operation-contracts) for server delays,
idempotency keys, and the retry settings an operation declares.

### Views

A *view* is what `with_options(...)` returns: an object with the same resources and methods as its client, whose
settings are the client's with the given ones replaced. In the example above, `traced` sends an extra header and has a
30-second budget, while `client` is unchanged. A view shares its client's connections and needs no closing; closing the
client closes it too. Use a view for a group of calls with other settings, and `options=RequestOptions(...)` for one
call. A view's `default_headers` and `default_query` add to the client's, and its other settings replace them.

### Use your own HTTPX2 client

`http_client=` takes an `httpx2.Client`, or an `httpx2.AsyncClient` for `AsyncClient`, configured as you need: TLS,
proxies, connection limits, HTTP/2, event hooks, or a transport such as the `MockTransport` of the examples. The client
borrows it and never closes it, so close it after the client. Without one, the client creates
`httpx2.Client(timeout=httpx2.Timeout(600, connect=5))` and closes it on `close()` or at the end of `with`. See
[Instrumentation](python-client-reference.md#instrumentation) and
[Redirects and transport construction](python-client-reference.md#redirects-and-transport-construction).

## Authenticate

Generated clients compile root security inheritance and operation overrides from OpenAPI. `Client` and `AsyncClient`
take one keyword argument per security scheme an operation requires, named after the scheme in snake case; a package
whose operations have no credentialed security alternative takes no credentials, copies no credential runtime, and
exports no `AuthError`. An argument whose name another constructor argument or scheme takes is suffixed, such as
`timeout_1` for a scheme named `timeout`, and so is the PascalCase prefix of OAuth provider classes that another
scheme's prefix takes, as model class names are.

An API key or bearer argument takes a string, and an HTTP Basic one a `(username, password)` tuple, which is encoded
as UTF-8, the charset of RFC 7617, which the generated server reads. Each also takes a callable returning its value, which the client calls for each request, so a rotating
token or a key read from a secret store stays current; a bearer argument also takes an OAuth provider. A callable's
failure raises `AuthError` with the reason `provider_failed` before the request is sent, and a value of the wrong type
`ConfigurationError` with the reason `invalid_type`. A credential sent in a header, such as `Bearer <token>`, must be
[header text](python-client-reference.md#model-codecs), as every header value: HTAB, SP, and visible ASCII without
whitespace at either end, so an empty bearer token, a key with a space at its end, a line break, or `café` raises
`ConfigurationError` with the reason `invalid_value` and the scheme's argument as `field_path` before sending; a key
with an inner tab is sent. A cookie credential must be a cookie value: visible ASCII without `"`, `,`, `;`, or `\`. No
environment variables or credentials are discovered by default.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.auth -->
<!-- fmt: off -->

```python
from app.client import Client
from app.client.errors import ConfigurationError
from fake import http_client

with Client(bearer="s3cret", http_client=http_client()) as client:
    client.pets.get_pet(pet_id=1)

tokens = iter(["token-1", "token-2"])
with Client(bearer=lambda: next(tokens), http_client=http_client()) as client:
    client.pets.get_pet(pet_id=1)
    client.pets.get_pet(pet_id=2)

with Client(http_client=http_client()) as client:
    try:
        client.pets.get_pet(pet_id=1)
    except ConfigurationError as error:
        print(error.reason)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.auth -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.auth-output -->
<!-- fmt: off -->

```text
> GET https://eu.shelter.example/v1/pets/1 authorization: Bearer s3cret
> GET https://eu.shelter.example/v1/pets/1 authorization: Bearer token-1
> GET https://eu.shelter.example/v1/pets/2 authorization: Bearer token-2
missing_credentials
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.auth-output -->

The bearer token goes to the `Authorization` header, a callable is called for each request, and a call that needs
credentials that the client lacks raises `ConfigurationError` with the reason `missing_credentials` before sending.
`get_health` declares `security: []`, so it needs no credentials.

A call sends the credentials of its operation's first security alternative they all satisfy: an AND alternative
needs all its schemes, and an OR list is tried in declared order. Each credential goes to the header, query field, or
cookie its scheme declares, replacing a value a client, view, or call header or a parameter put there, and only to the server's
origin: a page a server links at another origin, and `request_raw`, carry none of them. Absent security, explicit
`[]`, and an empty alternative are anonymous choices that apply only when no other alternative is satisfied, so an
optional operation sends a credential given for a listed scheme and, with none, sends nothing. A required operation that no credential satisfies raises `ConfigurationError` with the reason
`missing_credentials` before sending, unless the HTTP client has an Auth of its own, which it then uses. The client
authorizes no scopes: the resource server decides, and a 403 is terminal.

`auth` of the client, a view, or a call's `RequestOptions` takes any `httpx2.Auth`, which replaces the credentials
for those calls, and `auth=None` sends without an Auth; it cannot make a required operation anonymous. Unset, the
credentials apply, or else the HTTP client's own `auth`. Credentials given beside `Client(auth=...)` or an injected
HTTP client with an `auth` raise `ConfigurationError` with the reason `conflicting_auth`, since one
request runs one Auth flow.

Declare an API-specific challenge-less 401 contract in the operation's `runtime` setting of
[`--client-operations`](#per-operation-settings). It is false unless explicitly set and is recorded under
`client-operations."<pointer>".runtime.auth_challenge_less_401` in the generated README. It lets an OAuth provider
renew its token after a 401 without a `WWW-Authenticate` challenge. It is not a client option or an inferred response
behavior.

```toml
[tool.datamodel-codegen.client-operations]
"/paths/~1challenge-less/get" = { runtime = { auth_challenge_less_401 = true } }
```

### Sign requests with an HTTPX2 Auth

Request signing is an `httpx2.Auth` of your own, given as `auth`. Its flow sees the final request, body included,
after the client framed it; set `requires_request_body = True` to read a streamed body first. HTTPX2 runs it once per
send, and every retry sends the original request through it again. Here the signer also places the bearer token, since `auth` replaces the client's credentials:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.signing -->
<!-- fmt: off -->

```python
import hashlib
import hmac
from collections.abc import Generator

import httpx2

from app.client import Client
from fake import http_client


class BodySigner(httpx2.Auth):
    requires_request_body = True

    def __init__(self, key: bytes, token: str) -> None:
        self.key = key
        self.token = token

    def auth_flow(self, request: httpx2.Request) -> Generator[httpx2.Request, httpx2.Response, None]:
        digest = hmac.digest(self.key, request.method.encode() + b"\n" + request.content, hashlib.sha256)
        request.headers["Authorization"] = f"Bearer {self.token}"
        request.headers["X-Signature"] = digest.hex()
        yield request


with Client(http_client=http_client()) as client:
    signed = client.with_options(auth=BodySigner(b"signing-key", "s3cret"))
    print(signed.pets.create_pet(name="Kiki"))
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.signing -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.signing-output -->
<!-- fmt: off -->

```text
> POST https://eu.shelter.example/v1/pets content-type: application/json authorization: Bearer s3cret x-signature: aebceadaa214619bd8402dec14456b4df1c8fd2fe8f7b399365e8b594e6aa679 {"name":"Kiki"}
id=3 name='Kiki' tag=None
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.signing-output -->

A signature header other than `Authorization` is copied to a redirect HTTPX2 follows; set `follow_redirects=False`
for signed calls whose redirects may leave the server's origin.

Credential values do not appear in repr. A credential placed in the query is part of the request URL,
which HTTPX2 logs at INFO level on its `httpx2` logger, so keep that logger above INFO wherever URLs must stay
private. Errors retain safe metadata and their causes, which can hold an exception a credential callable raised;
apply your own policy before logging causes.

### OAuth providers

A package whose operations require an OAuth 2 or OpenID Connect scheme exports `ClientCredentials`, `RefreshToken`,
and `TokenSet` from its `auth` module, and one subclass for each declared flow whose token URL the API declares, such
as `OauthClientCredentials` for the `oauth` scheme's client credentials flow. A subclass requests tokens from its
declared URL unless `token_url` names another; the base classes need `token_url`. A provider is a bearer credential:
the call that needs a token requests it inline while holding the provider's lock, a `threading.Lock` or an
`asyncio.Lock` on the event loop the provider is used on, concurrent calls wait for that token, and nothing runs in
the background or is persisted. The shelter's `oauth` scheme declares a client credentials flow, so its package has
`OauthClientCredentials`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.oauth -->
<!-- fmt: off -->

```python
from app.client import Client
from app.client.auth import OauthClientCredentials
from fake import http_client

provider = OauthClientCredentials(client_id="shelter-cli", client_secret="pa55", scopes=("pets.read",))
with Client(oauth=provider, http_client=http_client()) as client:
    client.pets.get_pet(pet_id=1)
    client.pets.get_pet(pet_id=2)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.oauth -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.oauth-output -->
<!-- fmt: off -->

```text
> POST https://auth.shelter.example/token content-type: application/x-www-form-urlencoded authorization: Basic c2hlbHRlci1jbGk6cGE1NQ== grant_type=client_credentials&scope=pets.read
> GET https://eu.shelter.example/v1/pets/1 authorization: Bearer issued-1
> GET https://eu.shelter.example/v1/pets/2 authorization: Bearer issued-1
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.oauth-output -->

The provider requested one token and sent it with both calls.

`ClientCredentials` requests a confidential client's own token. Its request sends the `scopes` in order and the
`audience` when one is given, and authenticates the client with `client_secret_basic` (the default) or
`client_secret_post`; the `client_secret` is a string or a callable returning one, called for each token request.

`RefreshToken` keeps an access token current with the refresh token grant, starting from the `TokenSet` an authorization
produced. The provider alone refreshes it: no other provider or process may send the same refresh token, and since
synchronous calls and each event loop renew under a lock of their own, use it from one of them at a time. Its client
authentication defaults to `none`, which sends the `client_id` of a public client. For a scheme with an authorization code flow, construct the subclass from the `TokenSet` your
authorization produced, as `OauthRefreshToken(tokens, client_id="pets-app", on_token_refreshed=save)`, and pass it as
the scheme's credential, such as `Client(oauth=provider)`.

Each successful refresh makes a new `TokenSet` current, keeping the refresh token sent when the response gives none,
and then passes it to `on_token_refreshed` while the provider still holds its lock, so an application can persist each
token set in order; for an async client the callback may return an awaitable, which is awaited. An exception the
callback raises reaches the caller, and the refreshed token set stays current. The callback must not call its own
provider. A `TokenSet` needs a timezone-aware `expires_at` when its access token expires, and its repr omits both
tokens. `invalid_grant` raises `AuthError` with the reason `reauthorization_required`, and the application starts a
new authorization; a token set without a refresh token serves its access token until it expires or a resource rejects
it, and then raises the same error without a request.

A provider serves its token until a tenth of its lifetime, at most thirty seconds, remains, and then the call that
finds it due requests another; a token without `expires_in` is kept until a resource rejects it. When an early renewal
fails, the call keeps using the current token until it expires, and each later call in that margin tries the renewal
again. A 401 whose `WWW-Authenticate` has a Bearer
`invalid_token` error, or a 401 without a challenge on an operation declaring `auth_challenge_less_401`, renews the
token once, unless another call already replaced it, and sends the request again when its body can be sent again.
A 401 after a redirect, and a WebSocket handshake's, renews nothing.

Token requests go through the client's HTTP client without its Auth and without following redirects, with the calling
request's timeouts, or through the provider's own `http_client` when one is given, which keeps its own settings. The
client's HTTP client runs its event hooks on these token requests and responses, which carry the client authentication
and tokens. Used as an `httpx2.Auth` elsewhere, a provider needs its own `http_client`. The token URL must be HTTPS, or
HTTP to a loopback host. A rejection, an unexpected status, or a response that is not a JSON object with a Bearer
`access_token` raises `AuthError` with the reason `oauth_error`, a rejection keeping its `status_code` and standard
`oauth_error` code, and an `expires_in` that is not a positive number, or a refreshed one past the last date Python can
hold, the reason `invalid_expiry`. A transport failure
raises `AuthError` with the reason `oauth_error`, or `timeout`, and the native exception as its cause, which can hold
the token request and its client authentication. A provider's `clock=Clock(...)` times its token expiry.

## Handle errors

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.errors -->
<!-- fmt: off -->

```python
from app.client import Client
from app.client.errors import APIConnectionError, APIStatusError, NotFoundError
from fake import http_client

with Client(bearer="s3cret", http_client=http_client()) as client:
    try:
        client.pets.get_pet(pet_id=99)
    except NotFoundError as error:
        print(error.status_code, repr(error.body))

    try:
        client.adoptions.adopt_pet(pet_id=1)
    except APIStatusError as error:
        print(type(error).__name__, error)

    offline = client.with_options(base_url="https://offline.example/v1", max_retries=0)
    try:
        offline.pets.list_pets()
    except APIConnectionError as error:
        print(type(error).__name__, error.reason, repr(error.cause))
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.errors -->

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.errors-output -->
<!-- fmt: off -->

```text
> GET https://eu.shelter.example/v1/pets/99 authorization: Bearer s3cret
404 Error(message='/pets/99 not found')
> POST https://eu.shelter.example/v1/pets/1/adoption authorization: Bearer s3cret
ConflictError Error code: 409 - {"message":"Mimi is already adopted"}
APIConnectionError None ConnectError('connection refused')
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.errors-output -->

Every exception the client defines derives from `SDKError` and comes from `client.errors`; Python's own exceptions,
such as `TypeError` for an unknown keyword, pass through unchanged. A declared error status raises the subclass of
its status with the body decoded by the declared error schema, as `NotFoundError` and `ConflictError` do above; catch
`APIStatusError` for any of them. A failure to reach the server raises `APIConnectionError` with the HTTPX2 exception
as `cause`.

| Exception | Raised for |
|---|---|
| `APIStatusError` | A final status the operation does not declare as a success. Its subclasses are `BadRequestError` (400), `AuthenticationError` (401), `PermissionDeniedError` (403), `NotFoundError` (404), `ConflictError` (409), `UnprocessableEntityError` (422), `RateLimitError` (429), and `InternalServerError` (500 and above); it has `status_code`, `headers`, and `body` |
| `APIConnectionError` | A transport failure, after the retries it allows |
| `APITimeoutError` | A subclass of `APIConnectionError`: a phase timeout, or the call's `total_timeout` |
| `DecodeError` | An argument that cannot be sent, or a response that does not decode into its model |
| `ConfigurationError` | A setting, argument, or call the client refused before sending, with a `reason` and a `field_path` |
| `AuthError` | A credential callable or an OAuth token request that failed |

Each also has `reason`, `operation_id`, `info` (the `ResponseInfo` when a response arrived), `cause`, `attempt_count`,
`elapsed`, and `request_id`. Messages name no payload, header, or credential. See
[Errors](python-client-reference.md#errors) for every field and reason.

## Test code that uses the client

Test your own code against an `httpx2.MockTransport` instead of a server: pass an HTTPX2 client with that transport as
`http_client`, and answer each request in a function. Given a module that uses the client:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.shelter -->
<!-- fmt: off -->

```python
from app.client import Client
from app.client.errors import NotFoundError


def describe(client: Client, pet_id: int) -> str:
    try:
        pet = client.pets.get_pet(pet_id=pet_id)
    except NotFoundError:
        return f"No pet {pet_id}"
    return f"{pet.name} ({pet.tag or 'no tag'})"
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.shelter -->

its tests build the client in a fixture:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.test -->
<!-- fmt: off -->

```python
from collections.abc import Iterator

import httpx2
import pytest

from app.client import Client
from shelter import describe

PETS = {"/v1/pets/1": {"id": 1, "name": "Mimi", "tag": "cat"}}


def answer(request: httpx2.Request) -> httpx2.Response:
    assert request.headers["Authorization"] == "Bearer test-token"
    if (pet := PETS.get(request.url.path)) is None:
        return httpx2.Response(404, json={"message": "Not found"})
    return httpx2.Response(200, json=pet)


@pytest.fixture
def client() -> Iterator[Client]:
    with (
        httpx2.Client(transport=httpx2.MockTransport(answer)) as http,
        Client(bearer="test-token", http_client=http) as client,
    ):
        yield client


def test_describe(client: Client) -> None:
    assert describe(client, 1) == "Mimi (cat)"


def test_describe_missing(client: Client) -> None:
    assert describe(client, 2) == "No pet 2"
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.test -->

```bash
uv add --dev pytest
uv run pytest test_client.py
```

When the API is a FastAPI application you can import, such as one [generated from the same document](fastapi-server.md),
FastAPI's `TestClient` is an `httpx2.Client` too: pass `http_client=TestClient(app)` and
`base_url="http://testserver"` to call the application in the test process, without a server.

## Regenerate after the document changes

Run the same command again after the OpenAPI document changes. The methods change with the operations, so type
checkers point at the calls to update. As for models, every generation overwrites every generated file of the package, also one you edited, and never
deletes one. The modules of a resource that is no longer generated stay until you delete them: `--check` lists
them as extra files, and a generation that leaves such `.py` files in place names them in one
`LeftoverFilesWarning`, which Python shows once per process for the same text, also under `--watch` and repeated
`generate()` calls. Silence exactly this warning with
`warnings.simplefilter("ignore", datamodel_code_generator.LeftoverFilesWarning)` around `generate()`, or with
`ignore::datamodel_code_generator.LeftoverFilesWarning` in pytest's `filterwarnings`. Keep your own code outside
the package, because `--check` treats every `.py` file under `--client-output` as generated. The models can live inside the package, such as `--output app/client/models.py` with
`--client-model-package app.client.models`, as for the [server package](fastapi-server.md#the-generated-package).

`--check` compares without writing and prints the differences as for models, and `--output-format json`
emits the model generation and check payloads, as with `--generate-server`; their `target` names the package and
the runtime dependencies of the `uv add` notice, such as `{"package": "app.client", "dependencies": ["httpx2>=2.13.0",
"typing-extensions>=4.16", "pydantic>=2.14.0"]}`. The generation payload adds the next steps of the notice: the
package `readme`, with a path relative like those of `files`, and `usage`, the code that calls the first operation.
`--diff-against` and `--watch` also work
as they do with `--generate-server`. Use `--check` in CI to fail when the package is out of date; see
[Check in CI](fastapi-server.md#check-in-ci), which applies to the client as well.

## Configure generation

### Requirements

Like the server, the client needs Python 3.11 or later, both to run `datamodel-codegen` and as the target Python
version. As for the server, a setting the client needs that you leave unset takes the value it needs, and a value you
set that it cannot use is refused; see the server's [Requirements](fastapi-server.md#requirements), which also
describes the notice that shows how to set them and `target.implied`. An unset target Python version is `3.11`; one
below 3.11 that you or a preset set is refused.

Settings of the generated client that change how its methods are declared or checked do not change the models: the
same OpenAPI document and model settings produce the same model files whichever client settings you choose.

The model's `openapi_scopes` must include `api`, so that the models cover the parameters, bodies, and responses of
the operations: unset, it is `schemas api`; scopes you give without `api` stop the run with
`Error: --generate-client requires --openapi-scopes to include api` and exit code 2, and the Python API raises
`datamodel_code_generator.Error`. The client keeps every model setting
as given, including the generation timestamp, which `disable_timestamp` leaves out. The client files are headed,
formatted, and encoded like the model files, by the same model settings: `formatters`, `custom_formatters` and
`custom_formatters_kwargs`, `custom_file_header`, `custom_file_header_path` and `custom_file_header_mode`,
`disable_timestamp`, `enable_version_header`, `enable_command_header`, `use_double_quotes`,
`builtin_format_line_length`, `encoding` (for the Python files; the other files are UTF-8), `settings_path`, and
`use_type_checking_imports`. As for the models, Ruff moves imports only an annotation uses into `TYPE_CHECKING`
blocks when `ruff-check` runs with its TC rules selected and `use_type_checking_imports` allows it: by default for
the dataclass, TypedDict, and msgspec backends, and with `use_type_checking_imports` for the Pydantic ones; the
client reads no annotation at run time. As for the models, `typing.get_type_hints` on a generated class or function
whose annotations name a moved import then raises `NameError`: pass `--no-use-type-checking-imports`, or do not
select the TC rules, to introspect the annotations at run time. Custom
templates and custom formatters must keep the class and field names of the models: the client binds each operation
to the names in the generated model graph and does not read the rendered model source.

The generated package needs `httpx2>=2.13.0` and the other requirements of the printed `uv add` command. With Pydantic
models the minimum is `pydantic>=2.14.0`. An explicit `--target-pydantic-version` older than that minimum (`2`, `2.11`
or `2.12`) is refused with `Error:` and exit code 2 for those models; leave it unset or use `2.14`. The other model
backends do not use the option.

`--use-missing-sentinel` needs `--target-pydantic-version 2.14`, with which the models import `MISSING` from
`pydantic`; with the sentinel, an unset target is `2.14`. Model generation alone imports it from
`pydantic.experimental.missing_sentinel`, which pydantic 2.14 deprecates, when the target is unset or `2.12`, and
refuses the option for `2` and `2.11`. With a target of `2`, `2.11`, or `2.12` that you set, client generation
stops with `Error: The client target needs --target-pydantic-version 2.14 for --use-missing-sentinel, so that the
models import MISSING from pydantic` and exit code 2.

A `pydantic_v2.dataclass` field cannot tell an unset member from one set to `None`, so client generation with
`--output-model-type pydantic_v2.dataclass` needs `--use-missing-sentinel`, and with it
`--target-pydantic-version 2.14`: unset, the sentinel is on and the target is `2.14`. With the sentinel turned off,
`use-missing-sentinel = false` in `pyproject.toml` or `use_missing_sentinel=False` for `generate()`, generation
stops with `Error: The client target needs --use-missing-sentinel with --target-pydantic-version 2.14 for
'pydantic_v2.dataclass' models, whose fields cannot tell an unset member from None` and exit code 2. With both, an optional field without a default holds `MISSING`, as it
does for `pydantic_v2.BaseModel` when the options are set:

```python
from app.client import Client
from app.models import NewPet
from pydantic import MISSING

with Client() as client:
    client.pets.create_pet(body=NewPet(name="Mimi"))  # tag holds MISSING, so the request leaves it out
    if client.pets.get_pet(pet_id=1).tag is MISSING:
        print("the response left tag out")
```

A field the constructor is not given holds `MISSING` and is left out of a request; give `None` to send `null` where
the property is nullable. A member a response leaves out decodes to `MISSING`, and a `null` that its property does not
allow is refused with a `DecodeError` whose reason is `invalid_value`.

msgspec decodes a union of structs only when every struct in it is tagged, and an Enum only when its members are
all `str` or all `int` values, so client generation with `--output-model-type msgspec.Struct` needs
[`--use-msgspec-tagged-unions`](cli-reference/model-customization.md#use-msgspec-tagged-unions) and
[`--use-msgspec-nullable-enum-alias`](cli-reference/model-customization.md#use-msgspec-nullable-enum-alias), whether
or not the document declares a discriminated union or an enum that lists `null`: unset, both are on. With one turned
off in `pyproject.toml` or for `generate()`, generation stops with exit code 2 and an error that names every one
turned off, such as `Error: The client target needs
--use-msgspec-tagged-unions for 'msgspec.Struct' models, so that their discriminated unions can be decoded; The
client target needs --use-msgspec-nullable-enum-alias for 'msgspec.Struct' models, so that their enums that list null
can be decoded`, and the Python API raises `datamodel_code_generator.Error`. A union of structs that has no
discriminator, or that the option still leaves untagged (with a warning that names the reason), cannot be decoded: a
call that receives it fails with an `APIConnectionError` whose cause is msgspec's `TypeError`.

### Generator options

Every client setting is an option, a key of `[tool.datamodel-codegen]` in `pyproject.toml`, and an option of
`generate()` for the [Python API](#python-api):

| Option | `pyproject.toml` key | `generate()` option | Default |
|---|---|---|---|
| [`--generate-client httpx2`](cli-reference/target-generation-options.md#generate-client) | `generate-client` | `generate_client` | off |
| [`--client-output`](cli-reference/target-generation-options.md#client-output) | `client-output` | `client_output` | required |
| [`--client-package`](cli-reference/target-generation-options.md#client-package) | `client-package` | `client_package` | required |
| [`--client-model-package`](cli-reference/target-generation-options.md#client-model-package) | `client-model-package` | `client_model_package` | required |
| [`--client-signature-style`](cli-reference/target-generation-options.md#client-signature-style) | `client-signature-style` | `client_signature_style` | `"explicit"`; see [Signature style](python-client-reference.md#signature-style) |
| [`--client-body-arguments`](cli-reference/target-generation-options.md#client-body-arguments) | `client-body-arguments` | `client_body_arguments` | `"body"`; see [Request bodies](#request-bodies) |
| [`--client-resource-names`](cli-reference/target-generation-options.md#client-resource-names) | `client-resource-names` | `client_resource_names` | none: a resource for each first tag, and `default` for operations without a tag |
| [`--client-operations`](cli-reference/target-generation-options.md#client-operations) | `client-operations` | `client_operations` | none; see [Per-operation settings](#per-operation-settings) |
| [`--client-default-base-url`](cli-reference/target-generation-options.md#client-default-base-url) | `client-default-base-url` | `client_default_base_url` | none; see [Base URLs and servers](#base-urls-and-servers) |
| [`--client-server-base-url`](cli-reference/target-generation-options.md#client-server-base-url) | `client-server-base-url` | `client_server_base_url` | none; see [Base URLs and servers](#base-urls-and-servers) |
| [`--client-protocols`](cli-reference/target-generation-options.md#client-protocols) | `client-protocols` | `client_protocols` | none; see [Protocol Helpers](python-client-helpers.md) |

`--client-resource-names`, `--client-operations`, and `--client-protocols` take a JSON object, inline or as the path
of a JSON file, as `--aliases` does; in `pyproject.toml` they are tables, or the path of a JSON file, and in
`generate()` mappings of the same shape. A value on the
command line takes precedence over the selected profile, which takes precedence over the base table, and a
command-line table replaces the whole table of `pyproject.toml`. An operation's own `body_arguments` takes precedence
over `--client-body-arguments`, wherever each comes from. Paths in `pyproject.toml`, including the JSON files of these
settings, are relative to its directory, and command-line paths are relative to the working directory. The documents
that operation references and helpers name are relative to the JSON file that holds them, however the file is given,
as a `$ref` is relative to its document; a file given through a symbolic link uses the link's directory. Without a
file, they are relative to the `pyproject.toml` directory for its tables, and to the working directory for inline JSON
on the command line and for mappings given to `generate()`.

`--client-resource-names` maps a tag to the dotted namespace of the resource its operations join, such as
`{"pets": "store.pets"}`; a tag that is the first tag of no operation stops the run with an error, as a group key of
`--server-router-names` that matches no group does on the server. Operations without a tag join the resource
`default`, as in `client.default.get_health()`, the name the generated FastAPI server gives their group. Its name is
derived like a tag's: beside a tag that also derives `default`, such as `default` or `Default`, the one declared first
keeps `default` and the other takes a number, such as `default_1`, as on the server. No `--client-resource-names` entry
names the operations without a tag, so the `resource` of a `--client-operations` entry moves one of them to another
resource. Such a move leaves the derived names as they are: a tag, or the operations without one, takes its place among
them from its first operation, moved or not, as the server's groups do. An explicit namespace is shared by everything
that names it: a tag mapped to `default`, or an operation whose `resource` is `default`, joins the resource of that
name.

`--generate-client` requires `--client-output`, `--client-package`, and `--client-model-package`, and a `--client-*`
option given on the command line requires `--generate-client`; both stop with `Error:` and exit code 2.
`--generate-client` also requires `--input-file-type openapi`: an input type left to detection, `auto`, or any other
type stops with `Error: --generate-client requires --input-file-type openapi, not auto` (naming the given type) and
exit code 2 before the input is read.
`--generate-client` cannot be used with `--generate-server`, and one selected on the command line replaces the other
selected in `pyproject.toml`. Client keys of `pyproject.toml` are validated like model keys, but have no effect while
no client is selected.

### Per-operation settings

`--client-operations` maps an operation reference, the JSON pointer of the path item method such as
`/paths/~1pets/get`, or a document and a pointer joined by `#`, to the settings of that operation, as the
[how-to project](#call-operations) does for `listPets`. A pointer escapes `~` as `~0` and `/` as `~1`, so the operation
`GET /pets/{petId}` is `/paths/~1pets~1{petId}/get`; the generated README lists the reference of every operation.

| Member | Value |
|---|---|
| `resource` | The dotted namespace of the operation's resource |
| `name` | The method name |
| `parameter_names` | Argument names keyed by location and name, such as `{"query:limit": "page_size"}` |
| `request_media_type`, `response_media_type` | The default media types of the body and of the result |
| `description` | The method docstring, over the operation's route or, with `--use-schema-description`, its summary and description |
| `body_arguments` | `"body"` or `"both"`, over `--client-body-arguments` |
| `body_field_names` | Keyword names of body fields, keyed by media type, then property, such as `{"application/json": {"petName": "pet_name"}}` |
| `runtime` | `request_id_header`, `success_statuses`, `retry_safety`, `idempotency` (`{"header_name": "Idempotency-Key"}`), `retry_after_ms_header`, `should_retry_header`, `auth_challenge_less_401`, and `accepted_content_encodings` |

```toml
[tool.datamodel-codegen.client-operations]
"/paths/~1pets/get" = { name = "list_all", parameter_names = { "query:limit" = "page_size" } }
"/paths/~1pets/post" = { runtime = { idempotency = { header_name = "Idempotency-Key" } } }
```

```bash
datamodel-codegen --client-operations '{"/paths/~1pets/get": {"name": "list_all"}}'
```

A member the client does not know, or a value it cannot use, stops generation with `Error:` and exit code 2, naming
the setting by the key it was given under, such as `--client-operations['/paths/~1pets/get'].runtime.retry_safety`;
`generate()` raises `datamodel_code_generator.Error` with the same message.

### Python API

`generate()` takes the client options with the model options. The choices are the enums `ClientType`,
`ClientSignatureStyle`, and `ClientBodyArguments` of `datamodel_code_generator`, whose string values also work, and
`client_resource_names`, `client_operations`, and `client_protocols` take mappings shaped like their JSON. The
how-to project's settings:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.howto.generate -->
<!-- fmt: off -->

```python
from pathlib import Path

from datamodel_code_generator import (
    ClientBodyArguments,
    ClientType,
    DataModelType,
    InputFileType,
    OpenAPIScope,
    generate,
)

generate(
    Path("openapi.yaml"),
    input_file_type=InputFileType.OpenAPI,
    openapi_scopes=[OpenAPIScope.Schemas, OpenAPIScope.Api],
    output_model_type=DataModelType.PydanticV2BaseModel,
    preset="standard-py312-20261015",
    output=Path("app/models.py"),
    generate_client=ClientType.HTTPX2,
    client_output=Path("app/client"),
    client_package="app.client",
    client_model_package="app.models",
    client_body_arguments=ClientBodyArguments.Both,
    client_operations={"/paths/~1pets/get": {"runtime": {"request_id_header": "X-Request-Id"}}},
)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.howto.generate -->

It publishes every change together and returns `None`, like model generation. Without an `output`, it writes nothing
but the model metadata and a remote lock update and returns every model and client file as `GeneratedModules`, under
the paths their import paths imply; see
[Generating a Server or Client Package](using_as_module.md#generating-a-server-or-client-package).
`load_pyproject_config()` reads the client keys of `pyproject.toml`, whose paths and documents resolve as they do on
the command line. The `uv add` notice and the next steps are command-line messages only.

### Batch jobs

A [named job](pyproject_toml.md#named-jobs-experimental) whose settings select the client generates it as a single run
does, under the rules of [server jobs](fastapi-server.md#batch-jobs): `client-output` must not overlap the outputs of
other jobs or contain the remote lock file, and `--all-jobs --watch` regenerates client jobs too. Jobs that each
select a server or a client may name the same models `output`, which the batch writes once; they must generate the
same models for it.

## Next steps

- [Python Client Protocol Helpers](python-client-helpers.md): generated pagers, polled long-running operations,
  resumable uploads, SSE and NDJSON streams, WebSockets, a response cache, and webhook verification, declared in a helper
  file.
- [Python Client Reference](python-client-reference.md): signature styles, body field arguments, model conversion,
  timeouts and clocks, instrumentation, retries and operation contracts, request compression, body replay, redirects,
  templates, and every error.

---

# Python Client Protocol Helpers

Source: https://datamodel-code-generator.koxudaxi.dev/python-client-helpers/

!!! warning "Experimental"

    HTTPX2 client generation is experimental. Its options, generated package, and template values may change. See
    [Experimental Features](experimental.md).

Many APIs repeat one pattern across their operations: a list split into pages, a job you start and then poll, a file
sent in chunks, or a stream of events. A *protocol helper* is generated code for one such pattern. You describe the
pattern once, in a JSON *helper file* that names the operations it uses, and generation adds an object at
`client.protocols.<name>` that runs the whole exchange, such as a pager that fetches every page.

This page covers the helper file first, then each helper kind: [pagination](#pagination-helpers),
[polling](#polling-helpers), [resumable uploads](#upload-helpers), [SSE](#sse-stream-helpers) and
[NDJSON](#ndjson-stream-helpers) streams, [WebSockets](#websocket-helpers), a [cache](#cache-helpers), and
[webhook verification](#webhook-verification-helpers). The [records, options, and exceptions](#records-options-and-exceptions)
the helpers share come last. Read [Python Client Generation](python-client.md) first: helpers build on the generated
client and its settings.

The examples use the layout of the guide's quick start: the generated package `app.client` and its models
`app.models`, inside the application package `app`. The text calls the generated package `client`, as in
`client.protocols`.

Terms used throughout:

- A *selector* reads a value from a response: a JSON pointer into its body, a header, or its status.
- A *request target* is where a helper writes a value into the next request: a parameter, or a member of the body.
- A *binding* copies a value into a request target: a literal, or what a selector reads from an earlier response.
- A *session* is one run of a helper, such as one pager or one polled operation. Each request in it is still its own
  call, with its own retries and timeouts, and the session's limits, such as `max_pages` or `total_timeout`, bound
  them all.
- A *checkpoint* is plain JSON that a helper returns so that a later session can continue where this one stopped.

## Configure helpers

Pagination, polling, SSE or NDJSON stream, WebSocket, webhook, cache, and resumable upload helpers of an API are declared
in a helper file, which [`--client-protocols`](cli-reference/target-generation-options.md#client-protocols) names. Generation validates every
helper and resolves its references against the selected API. An enabled
pagination helper generates the [pagination helper](#pagination-helpers) below, an enabled polling helper the
[polling helper](#polling-helpers), an enabled `offset` upload helper the
[upload helper](#upload-helpers), an enabled SSE helper the [SSE stream helper](#sse-stream-helpers), an enabled NDJSON
helper the [NDJSON stream helper](#ndjson-stream-helpers), an enabled WebSocket helper the
[WebSocket helper](#websocket-helpers), an enabled cache helper the [cache helper](#cache-helpers), and an enabled webhook helper the
[webhook verification helper](#webhook-verification-helpers). A disabled helper generates nothing, so the package is the
same as without it. The `parts` profile of `resumable_upload`
fails whether the helper is enabled or not, and its settings are not read yet; an enabled
upload helper declaring `abort` or `create.session_url` fails too.

| Setting | Values | Default | Where |
|---|---|---|---|
| `--client-protocols` | A helper file path, a JSON object, or none | None | `--client-protocols helpers.json` or inline JSON; `client-protocols = "helpers.json"` or a table in `pyproject.toml`; `generate()`: `client_protocols`, a mapping. The documents a helper file names are relative to the file; those of inline JSON or a mapping are relative to the working directory, and those of a `pyproject.toml` table to its directory |

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.protocols.pyproject -->
<!-- fmt: off -->

```toml
[tool.datamodel-codegen]
input = "options.yaml"
input-file-type = "openapi"
output = "app/models.py"
output-model-type = "pydantic_v2.BaseModel"
openapi-scopes = ["schemas", "api"]
target-python-version = "3.11"
formatters = ["builtin"]
disable-timestamp = true
generate-client = "httpx2"
client-output = "app/client"
client-package = "app.client"
client-model-package = "app.models"
client-protocols = "protocols.json"
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.protocols.pyproject -->

The helper file is read only when the target is generated, so its problems are reported then, with the target's
identity. Without `--client-protocols`, nothing is read.

### The helper file

The file holds one JSON object mapping each helper's name to its definition, in declaration order. Every definition
has an `enabled` flag, `true` by default. The example below sets `"enabled": false` on each helper: generation still
validates a disabled helper's definition, but generates nothing for it. Leave the key out, or set it to `true`, to
generate the helper:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.protocols.json -->
<!-- fmt: off -->

```json
{
  "users.all": {
    "kind": "pagination",
    "enabled": false,
    "operation": "/paths/~1users/get",
    "items": {"from": "body", "pointer": "/data"},
    "item_schema": {"pointer": "/components/schemas/User", "document": "../helpers.yaml"},
    "continuation": {
      "kind": "cursor",
      "read": {"from": "body", "pointer": "/next_cursor"},
      "write": {"in": "query", "name": "cursor"},
      "end": [{"kind": "missing"}, {"kind": "null"}],
      "empty_string": "value"
    },
    "bindings": [
      {
        "target": {"in": "header", "name": "snapshot"},
        "value": {"source": "initial", "selector": {"from": "header", "name": "Snapshot", "occurrence": "all"}}
      }
    ]
  },
  "jobs.run": {
    "kind": "polling",
    "enabled": false,
    "create": "/paths/~1jobs/post",
    "accepted_statuses": [202],
    "poll": "/paths/~1jobs~1{jobId}/get",
    "bindings": [
      {
        "target": {"in": "path", "name": "jobId"},
        "value": {"source": "initial", "selector": {"from": "body", "pointer": "/id"}}
      }
    ],
    "state": {"from": "body", "pointer": "/status"},
    "pending": ["queued", "running"],
    "succeeded": ["done"],
    "failed": ["failed"],
    "cancelled": ["cancelled"],
    "result": {
      "kind": "inline",
      "selector": {"from": "body", "pointer": ""},
      "schema": {"pointer": "/components/schemas/Job"}
    },
    "interval": {"seconds": 2, "retry_after_header": "Retry-After"},
    "remote_cancel": {
      "operation": "/paths/~1jobs~1{jobId}/delete",
      "bindings": [
        {
          "target": {"in": "path", "name": "jobId"},
          "value": {"source": "initial", "selector": {"from": "body", "pointer": "/id"}}
        }
      ]
    },
    "immediate_result": {
      "statuses": [200, 201],
      "selector": {"from": "body", "pointer": ""},
      "schema": {"pointer": "/components/schemas/Job"}
    },
    "expires_at": {"from": "body", "pointer": "/expires"}
  },
  "records.watch": {
    "kind": "ndjson",
    "enabled": false,
    "operation": "/paths/~1records/get",
    "media": "application/x-ndjson",
    "event_schema": {"pointer": "/components/schemas/Record", "document": "../helpers-external.yaml"},
    "completion": {"kind": "sentinel", "value": "[DONE]"},
    "final_line": "allow_eof",
    "resume": {
      "enabled": true,
      "cursor": {"from": "body", "pointer": "/id"},
      "write": {"in": "query", "name": "after"},
      "reopen_operation": "/paths/~1records/get",
      "delivery": "at_least_once",
      "missing": "inherit",
      "null": "clear",
      "expires_at": {"from": "header", "name": "X-Expires"}
    }
  }
}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.protocols.json -->

- The file is read as JSON options such as `--aliases` read a JSON file: UTF-8 text parsed by Python's `json`
  module, so a key repeated in one object keeps its last value. A file that cannot be read, text that is not JSON,
  including a path that names no file, and a value that is not an object fail with the message
  `--client-protocols` gives, such as `Invalid JSON for protocols: ...` or
  `Invalid protocols: Input should be a valid dictionary`. Before parsing,
  text that opens more than 64 arrays and objects at once fails the same way, with
  `Invalid JSON for protocols: nests collections deeper than 64 levels`. `NaN` and `Infinity`, which the parser
  accepts, are not JSON values for a literal.
- Every key is checked at every level. A key the definition does not have, including a setting of another kind or
  one that the chosen variant does not take, fails; a missing required key or a value of
  the wrong type fails; and settings that contradict each other fail.
- A helper name is Python identifiers separated by dots, each in NFKC form, not a keyword, not starting with `_`, and
  not a Windows device name such as `con` or `com1`. Two names equal after NFC normalization and case folding, or
  one name that is a dotted prefix of another, such as `users` and `users.all`, fail.
- Every definition has `kind`, one of `pagination`, `polling`, `sse`, `ndjson`, `websocket`, `webhook`, `cache`,
  and `resumable_upload`, and `enabled`, a boolean that defaults to `true`.

### Shared values

| Value | Forms |
|---|---|
| Operation reference | An RFC 6901 pointer string to a root path operation, or `{pointer, document?}`. A document names the root input, relative to the helper file, or without a file to the working directory, or to the `pyproject.toml` directory for its table |
| Schema reference | `{pointer, document?}` with an RFC 6901 pointer; an omitted document is the root input. A document, resolved as for operation references, must be one of the accepted input's documents |
| Selector | `{from: body, pointer}`, an RFC 6901 pointer over wire names; `{from: header, name, occurrence?}` with `occurrence` `single` (default) or `all`; or `{from: status}`. `all` is accepted only in a binding value |
| Request target | `{in: path\|query\|header\|cookie, name}`, `{in: querystring, name, pointer}` with the declared querystring's name, or `{in: body, pointer}` |
| Binding | `{target, value}`, where `value` is `{source, selector}` with `source` `input`, `initial`, or `previous`, or `{literal}` with any JSON value whose text is UTF-8 and whose containers nest at most 64 levels |
| End condition | `{kind: missing}`, `{kind: "null"}`, or `{kind: value, value}` with a JSON value other than null. A list of them is nonempty and names each condition once |

A reference must select a root path operation of the input, or generation fails; webhooks,
path items of other documents, and paths that `--openapi-include-paths` leaves out are refused. Each request target
must exist in the operation it writes to: the declared parameter of that location and name, header names compared
without case, the operation's own querystring, or its request body. An operation that owns a querystring takes no
`in: query` target.

### Helper kinds

| Kind | Required | Optional |
|---|---|---|
| `pagination` | `operation`, `items` (a body selector), `item_schema`, `continuation` | `bindings` (`[]`), such as a snapshot token each request carries |
| `polling` | `create`, `accepted_statuses`, `poll`, `bindings` (create to poll), `state`, `pending`, `succeeded`, `result` | `failed` and `cancelled` (`[]`), `interval` (`{seconds: 1, retry_after_header: null}`), `remote_cancel` (`{operation, bindings?}`), `immediate_result` (`{statuses, selector, schema}`), `expires_at` |
| `sse`, `ndjson` | `operation`, `media`, `event_schema`, `completion`, and for `ndjson` `final_line` (`require_newline` or `allow_eof`) | `unknown` (`error`, the default, or `raw`), `error_events` (`{}`), `resume` (`{enabled: false}`) |
| `websocket` | `operation` (a GET without a body), `send`, `receive` (each `{codec: json\|utf8\|bytes, frame?, schema?}`) | `subprotocols` (`[]`), `enabled` (`true`) |
| `webhook` | `event_schema`, `signature` (see [webhook verification helpers](#webhook-verification-helpers)) | None |
| `cache` | `operation`, `validator` (`etag`, `last_modified`, or `both`), `authenticated` (a boolean) | `statuses` (`[200]`), `vary_allowlist` (`[]`); see [cache helpers](#cache-helpers) |
| `resumable_upload` | `profile` (`offset`), `create` (`{operation, size?, expires_at?}`), `probe` (`{operation, remote_offset, bindings?}`), `append` (`{operation, offset, length?, checksum?, bindings?}`, a `checksum` being `{target, algorithm, encoding?, algorithm_prefix?}`), `partial_commit` (`allowed` or `forbidden`), `completion` | `abort` (`{operation, bindings?}`) and `create.session_url`, both refused as not supported yet |

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.cache.fields -->
Cache helper fields: `operation`, `validator`, `authenticated`, `statuses`, `vary_allowlist`, `enabled`. See [cache helpers](#cache-helpers).
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.cache.fields -->

A pagination `continuation` is one of these:

| `kind` | Settings |
|---|---|
| `cursor` | `read`, `write`, `end`, and `empty_string` (`value` or `end`), which alone decides the empty string, so `end` cannot list it |
| `offset`, `page` | `write`, `first` (an integer of at least 0), `step` (`{literal: <positive integer>}` or `{page_items_count: true}`), and exactly one of `has_more` and `total` |
| `next_url` | `read`, `end`, and `repeat_request_body` (`false`) |
| `link` | `header`, the response header's name, and `rel` (`next`) |

Polling statuses are distinct integers from 100 to 599, and `immediate_result` cannot list an accepted status. The
four state lists hold JSON values: a list that repeats a value fails, and a value that two lists
share fails. `result` is `{kind: inline, selector, schema}`,
`{kind: operation, operation, bindings?}`, or `{kind: none}`, and `interval.seconds` is positive.

An upload's `completion` is `{kind: length}` or `{kind: operation, operation, result_schema, bindings?}`. The `parts`
profile is refused without reading its other settings.

A stream's `event_schema` is one schema reference, or `{discriminator, mapping}` where `discriminator` is
`{from: event_type}` (SSE only) or `{from: body, pointer}` and `mapping` names the schema of each event type.
`unknown: raw` and `error_events` need a discriminator, and an error event cannot also be a mapped event. `completion`
is `{kind: eof}`, `{kind: sentinel, value}`, or `{kind: event_type, value}` (SSE only). An enabled `resume` takes
`cursor` (a selector, or `event_id` for SSE), `write`, `reopen_operation`, `delivery: at_least_once`, `bindings`
(`[]`), `reconnect_on` (a nonempty list of `transport_interruption` and `incomplete_eof`, by default
`[transport_interruption]`), and optionally `expires_at`; a selector cursor also takes `missing` (`inherit` or
`error`) and `"null"` (`clear` or `error`). A disabled `resume` takes no other key.

Helpers reserve the arguments `pagination_options`, `poll_options`, `stream_options`,
`ws_options`, `cache_options`, `upload_options`, `source`, `items`, and `state`. When
an enabled helper's operation, or its `create` operation for polling and uploads, has a parameter or field argument
derived from one of these names, the argument takes the model's suffix, such as `items_1`; an explicit name of
`parameter_names`, `body_field_names`, or `--aliases` that takes one fails generation instead of being renamed:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.protocols.diagnostics -->
<!-- fmt: off -->

```text
--client-protocols['tags.all']: The pagination helper 'tags.all' reserves the argument 'items' of GET /tags; rename them with the operation's parameter_names or body_field_names in --client-operations
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.protocols.diagnostics -->

### Helpers in Python

`generate()` takes the object of the helper file as a mapping in `client_protocols`, validated as the file is, with
the same messages:

```python
from pathlib import Path

from datamodel_code_generator import generate

generate(
    Path("openapi.yaml"),
    input_file_type="openapi",
    openapi_scopes=["schemas", "api"],
    output_model_type="pydantic_v2.BaseModel",
    target_python_version="3.11",
    output=Path("app/models.py"),
    generate_client="httpx2",
    client_output=Path("app/client"),
    client_package="app.client",
    client_model_package="app.models",
    client_protocols={
        "users.all": {
            "kind": "pagination",
            "operation": "/paths/~1users/get",
            "items": {"from": "body", "pointer": "/data"},
            "item_schema": {"pointer": "/components/schemas/User"},
            "continuation": {"kind": "link", "header": "Link"},
        },
    },
)
```

A file and the equal mapping generate the same package, as do references that name the root input explicitly and
ones that leave it implied.

### Helper settings on the client

Helper settings belong to the root client only: neither `with_options` nor `RequestOptions` takes them, and views share
the root's. A root takes `helper_defaults` when the package declares a helper, `cache_stores` when it declares a cache
helper, and `allowed_origins` when it declares a pagination helper that follows a server's next URL or `Link` header.

```python
from app.client import Client
from app.client.protocols import PaginationOptions

client = Client(helper_defaults={"users.all": PaginationOptions(max_pages=10, total_timeout=300)})
```

| Setting | Type | Meaning |
|---|---|---|
| `helper_defaults` | `Mapping[str, HelperOptions] \| None`, default `None`, where `HelperOptions` stands for the union of the six option classes and is not importable | The options of each helper, by helper name: `PaginationOptions`, `PollOptions`, `StreamOptions`, `CacheOptions`, `WSOptions`, or `UploadOptions`, of the helper's kind, each imported from `client.protocols`. The mapping is copied |
| `cache_stores` | `Mapping[str, CacheStore] \| None` (`AsyncCacheStore` on `AsyncClient`), default `None` | The store each [cache helper](#cache-helpers) keeps its entries in, by helper name. The mapping is copied and keeps each store's identity; the client borrows the stores and never closes them |
| `allowed_origins` | `Sequence[Origin] \| None`, default `None` | The origins beyond the server's that a next-URL or Link pagination helper may follow a URL to; an origin listed twice counts once |

The client checks these settings when it is constructed: a name that is no helper of the package raises
`ConfigurationError` with `unknown_field`, and options of another kind, or no options record, with `invalid_value`.
Explicit call options take precedence over these defaults, which take precedence over the effective defaults above.

## Pagination helpers

An enabled pagination helper, whatever its continuation, is generated at `client.protocols.<name>` on `Client` and
`AsyncClient` alike; the property exists only when the package has a helper. `page` fetches the first
page, `next_page` the page after one the helper returned, and `iterate` returns a pager, which sends nothing until it is
iterated; `resume` returns a pager continuing a pager's checkpoint. A helper takes the operation's parameters and its
body as keywords, never field arguments, then `pagination_options` and `options`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.pagination.helper -->
<!-- fmt: off -->

```python
    def page(
        self,
        *,
        cursor: str | UNSET = UNSET,
        limit: int | UNSET = UNSET,
        X_Snapshot: str | UNSET = UNSET,
        pagination_options: PaginationOptions | None = None,
        options: RequestOptions | None = None,
    ) -> Page[models.User, ListUsersResponse]:
        """Fetch the first page of GET /users."""
        return first_page(
            self._core,
            _plans.PLAN_0,
            (cursor, limit, X_Snapshot),
            pagination_options=pagination_options,
            options=options,
        )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.pagination.helper -->

```python
from app.client import Client

with Client() as client:
    helper = client.protocols.users.all
    for user in helper.iterate():
        print(user.id)
    first = helper.page()
    following = helper.next_page(first)
```

A `Page[T, P]` holds its `items` as a tuple of the item type, the decoded response as `data`, the response's
`ResponseInfo`, and the `continuation` after it: the server's cursor, the next offset or page number, or the resolved
next URL, as a `JSONValue`, or None on the last page. `Pager[T, P]` iterates over the items and `iter_pages()` over the
pages; `AsyncPager[T, P]` does the same with `async for`, and its `iter_pages()` is not awaited. `Page`, `Pager`, and
`AsyncPager` are imported from `client.protocols`, in every package. A pager fetches a page only once the previous one is
consumed and reads, decodes, and closes each page inside its own call, so leaving a loop early holds no response. Its
`progress` reports the pages fetched and the items delivered.

### Cursors and end conditions

A page's items must be a JSON array at the `items` pointer; an empty array does not end the traversal. The cursor is
read from the page's body, a response header, or its status, and written to the target of `write`: a path, query, or
header parameter, a property of the querystring, or a member of the JSON request body, never a position that carries
credentials. A cursor the server returned is sent as it came, without its target's codec, while a start cursor the
caller passes is encoded like any other argument. The traversal ends at a page whose cursor is missing or null where
the helper declares that end, is one of its end values, or is empty with `empty_string: end`. A missing or null cursor
that no end covers, missing or null items, a header repeated for a single cursor, and a value read for a path
parameter that makes its segment, encoded in the parameters' styles with the caller's own path arguments and the
helper's literals beside it, a dot segment (`.` or `..`, `%2E` in either case counting as `.`) raise
`ProtocolDataError` as a failure of the page's call. The error names the first such read value whose encoded text is
non-empty, or else the first one. A page is read whole like any response. A
continuation returned by an earlier page of the same pager, or an earlier page `next_page` continued from, ends it with
`ProtocolDataError` with the reason `pagination_cycle` after the repeating page.

### Offsets and page numbers

An `offset` or `page` continuation counts positions instead of reading them. The first request is sent as the caller
gives it. The traversal starts at the position the caller passes for the `write` target, read from the first request
after its usual encoding: the parameter's value, or the member at the pointer of the querystring or JSON body. An
integral number such as `40.0` on a `number` target starts at its integer. Without one it starts at `first`, the offset
or page number the server gives a request without one. A starting value that is not an integer fails like any invalid
argument, with a request `DecodeError` when its codec refuses it, and otherwise with `ProtocolDataError` (reason
`type`, location the target) before anything is sent. Each request after a page writes the page's position advanced by
the `literal` step, or for an offset by the page's item count with `page_items_count`; a page number always advances by
a literal step, and generation refuses `page_items_count` for it. The position is written to `write` like a cursor, so
its target must accept integers, and `Page.continuation` has the kind `offset` or `page`.

```json
{
  "users.by_offset": {
    "kind": "pagination",
    "operation": "/paths/~1users/get",
    "items": {"from": "body", "pointer": "/data"},
    "item_schema": {"pointer": "/components/schemas/User"},
    "continuation": {
      "kind": "offset",
      "write": {"in": "query", "name": "offset"},
      "first": 0,
      "step": {"page_items_count": true},
      "total": {"from": "header", "name": "X-Total-Count"}
    }
  }
}
```

The traversal ends at a page whose `has_more` reads `false`, or once the items counted before the next position reach
the `total` the page reads. For an offset they are the offsets past `first`, since a total counts the whole collection
wherever the traversal started; for a page number they are the items delivered since the start, the only count a page
number gives, and a page without items ends it too, since no later page can bring the count nearer. A `total` of 0 ends
at the first page, and a position past the total ends too. `has_more` must read a JSON boolean and `total` a JSON
integer of at least 0, which a number with a fraction or an exponent is only when its text is integral: `1.0` and
`1e0` count 1 and `9007199254740993.0` counts exactly that, while `9007199254740993.00000000000000000001` is mistyped,
since the total is read from the body's text rather than from a rounded float. A header spells `true` or `false`, or
decimal digits with an optional `-`, and generation checks
the types its declared schema gives. A missing, null, or mistyped value raises `ProtocolDataError`, and a negative
total, from the body or a header, raises it with the reason `value`. Otherwise an empty page does not end the
traversal, but one that continues while `page_items_count` counts items would ask for the same position again, so it
raises `ProtocolDataError` with the reason `inconsistent`. Positions only grow, so these helpers never raise
`ProtocolDataError` with the reason `pagination_cycle`.

### Next URLs and Link headers

A `next_url` or `link` continuation follows the URL a page gives. The first request is sent as the caller gives it, and
each later page goes to the URL the last page gave, as it came: the caller's query and the `default_query` or `extra_query` of
the client, a view, or the call are never laid over it, while the call's headers and the operation's header and cookie parameters
are sent again. A later page is a GET without a body, unless a next URL sets `repeat_request_body: true`, which sends
the operation's method with the caller's body again; generation refuses it unless the body may
be sent again as a 307 or 308 redirect sends it: the operation's method is GET, HEAD, OPTIONS, PUT, or DELETE, or its
`retry_safety` is `idempotent`. A `next_url` reads the URL with its `read` selector and ends like a cursor: at a missing
or null value only where an `end` condition says so, or at one of its end values, and a missing or null value no end
covers, or a value that is not a string, raises `ProtocolDataError`. A `link` continuation reads the RFC 8288 links of
the `header` field, every value of it, and follows the one whose `rel` lists the relation, `next` unless `rel` names
another; a page without that link is the last. An empty page with a next URL does not end the traversal.

```json
{
  "users.linked": {
    "kind": "pagination",
    "operation": "/paths/~1users/get",
    "items": {"from": "body", "pointer": "/data"},
    "item_schema": {"pointer": "/components/schemas/User"},
    "continuation": {"kind": "link", "header": "Link"}
  }
}
```

The Link header is read strictly. Links are separated by commas, each a `<URI-Reference>` followed by `;` and its
parameters, a token or a quoted string with backslash escapes, so a comma or semicolon inside quotes separates nothing;
empty list elements and the whitespace around separators are skipped. Parameter names and relation types match
without regard to ASCII case, a `rel` lists several relation types separated by spaces, and only a link's first `rel`
counts. A link with an `anchor` parameter describes another resource and is skipped. Any other syntax raises
`ProtocolDataError` with the reason `malformed`, and two links of the relation raise it with `inconsistent`.

A URL, from either continuation, resolves against the URL of the request that returned the page, after any redirect, as
RFC 3986 resolves a reference. A reference with characters outside RFC 3986, or with brackets anywhere but around an
IPv6 host, raises `ProtocolDataError` with `malformed`, and one with a fragment, user information, even empty, a scheme
other than `http` or `https`, or an invalid port raises it with `value`. The resolved URL excludes the query fields the
client's authentication places itself. The URL must name the origin of the server the operation is sent to, its scheme,
host, and port, or an origin the client's `allowed_origins` lists; any other origin raises
`ProtocolDataError` with `value` before anything is sent to it, and so does a `next_page` whose options select a server
whose origin the URL no longer shares or is allowed beside. A request to an allowed origin other than the server's, like a redirect to another origin, carries no
`Authorization`, `Proxy-Authorization`, `Cookie`, or `Cookie2` header, and none of the headers or query fields the
package's security schemes name, whether the authentication, a client, view, or call header, a parameter, a binding, or the server's URL
put them there; its other headers, the call's and the operation's, are sent as usual. The client's credentials are
placed only at the server's origin, so such a page is sent without them. A query credential the URL repeats is
removed before the client places its own. `Page.continuation` is the resolved server URL, and a URL an earlier
page of the session gave, or the URL of the first page itself, ends the traversal with `ProtocolDataError` with the reason
`pagination_cycle` after the repeating page; URLs compare once resolved and without the authentication's query fields, with the host's case, the
default port, and dot segments normalized, but not their percent-encoding.

### Bindings and request targets

Each request after the first is the first request with the helper's `bindings` written in order, then the cursor or
position. A binding writes a `literal`, or what its selector reads from the `initial` page's response, kept for the
whole traversal, or from the `previous` page's; a header selector with `occurrence: all` reads every value of the header
as an array. The bindings are read from every page that has a next page, even one a caller never continues, and a value
its selector finds missing raises `ProtocolDataError`; a header none of whose values is present counts as missing under
`occurrence: all` too. A next-URL or Link helper writes no cursor; its bindings write headers, and the JSON body only
when a next URL repeats it. A `null` is written as it is to a JSON body or a querystring of JSON content, the only
targets that can carry it. A parameter target replaces the argument. A querystring or body target writes into the
caller's querystring or JSON body, encoded and checked as in any call, or into an empty object when the call gives none;
a missing, null, or other non-object value on its pointer is replaced by an empty object. The querystring is then
encoded once, so no query pair is added. The values a server gave are never checked against their targets' schemas;
a header parameter still takes [header text](python-client-reference.md#model-codecs) only, as in any call. A
call's `extra_headers` and `extra_query` must not name a header or a query parameter the helper writes: `iterate`,
`page`, and `next_page` raise `ConfigurationError` with a `field_path` of `("options", "extra_headers" or
"extra_query", <name>)` before sending. A binding
with `source: input` is not supported yet.

### Pagination limits and sessions

A pager, and each `page` or `next_page` call, is one session. Every page is its own call, with its own retries, total
timeout, and idempotency key, and the session bounds all of them: a page's deadline is the earlier of its own and the
session's. Each limit comes from the call's options, then the helper's options in the client's
`helper_defaults`, then the default below:

| Limit | Default | None |
|---|---|---|
| `PaginationOptions.max_pages` | No limit | Removes the limit |
| `PaginationOptions.max_items` | No limit; 0 ends a pager at once without sending | Removes the limit |
| `PaginationOptions.total_timeout` | No limit | Removes the limit |

A limit reached while pages remain raises `SessionLimitError` with the progress so far; the last page ends normally even
exactly at a limit. An item limit is exact for items, while `iter_pages` checks it before each fetch, so a page that
crosses it is delivered whole, and `page` or `next_page` with `max_items=0` raises `SessionLimitError(reason="items",
limit=0)` without sending. Defaults naming a helper the package lacks, or giving it another kind's options, fail the
client's construction with `ConfigurationError`, and so do options of another type, and an idempotency key the call's
`RequestOptions` fixes, when a helper is called.

A pager is used by one consumer at a time and in one mode: stepping it while it fetches, closing it then, and
mixing items with pages raise `ConfigurationError` with the reason `invalid_state`. After a failure, cancellation
included, and after `close()`, every step raises it, and nothing is fetched again. Each page is an ordinary request
of the HTTP client, which its `event_hooks` see.

### Pagination checkpoints and resume

`pager.checkpoint()` returns the continuation the pager fetches its next page with: the server's cursor, the next
offset or page number, or the resolved next URL, the same value as `Page.continuation`. It sends nothing, on `Pager`
and `AsyncPager` alike, and is None before the first page and after the last. The helper's `resume(state, ...)` takes
that value with the operation's arguments and any request body again, as `iterate` takes them, and returns a pager in a
session of its own that sends nothing until it is iterated; it is not awaited, even on `AsyncClient`.

```python
from app.client import Client
from app.client.errors import SessionLimitError
from app.client.protocols import PaginationOptions

with Client() as client:
    helper = client.protocols.users.all
    pager = helper.iterate(limit=20, pagination_options=PaginationOptions(max_pages=5))
    try:
        for user in pager:
            print(user.id)
    except SessionLimitError:
        for user in helper.resume(pager.checkpoint(), limit=20):
            print(user.id)
```

A continuation is the server's value alone. It holds no call arguments, credentials, body, or progress, and nothing in
it names the helper, so the caller keeps it beside the arguments of the call it belongs to. It is JSON, which
`json.dumps` and `json.loads` round-trip.

A pager iterated by items that stops in the middle of a page gives the continuation before that page, so a resumed
pager fetches the page again and repeats the items already delivered from it; iterate with `iter_pages()` to checkpoint
between pages. `resume(None, ...)` starts at the caller's own first request, as `iterate` does. A checkpoint remains
available after a pager fails or is closed, and a pager fetching a page raises `ConfigurationError` with the reason
`invalid_state`.

A pager stopped by `SessionLimitError` or by `ProtocolDataError` with the reason `pagination_cycle` is resumed from its
`checkpoint()` like any other; the errors themselves carry no continuation. A page fetched with
`page` or `next_page` continues from its own `continuation`. An item limit that stops inside a page leaves the
continuation before that page, None inside the first one, so resuming with a `max_items` below the page size delivers
the same items again; raise the limit, or limit pages instead.

A resumed pager counts its pages and items from zero against its own limits, its session's timeout and deadline start
afresh, and it detects cycles from the given continuation on. The first resumed request writes the continuation and the
helper's literal bindings; a binding that reads a response has no value yet, so its target takes the caller's argument,
encoded as in any call, and an `initial` binding is read from the first resumed page. A page-number helper that ends at
a total counts the items from the resumed page on: where a first run ends at the page that completes the total without
another request, a resumed one asks for the page after it and ends there when that page has no items, or fails with
whatever error the server answers for a page past the end.

An offset or page number must be a nonnegative integer and a next URL a string, or `resume` raises
`ConfigurationError(field_path=("state",), reason="invalid_value")`, as it does for a value that is not JSON. A next URL
is checked as a server's: it must be absolute, without a fragment or user information, and name the origin of the
server or one the client's `allowed_origins` lists, or `resume` raises `ProtocolDataError` before anything
is sent. The query fields the client's authentication places itself are removed from it at once, so the pager's
`checkpoint()` and its requests are without them, and a request to an allowed origin other than the server's carries
credentials only as a server's next URL would. A cursor written to a path
parameter is refused as any call's path value is when it makes its segment a dot segment.

### Pagination generation checks

The operation must declare exactly one success response with one JSON media type and a schema, read natively, so an
operation that also declares a `204` or another success status is refused. The items pointer must name, through the
fields of the page's models, a JSON array whose items schema is `item_schema`. The cursor and each binding's selector
must read a declared property or header, and a querystring or body target's pointer must name a property its schema
declares, through `allOf` members and nullable `anyOf` or `oneOf` ones. The JSON types a cursor reads, other than null,
and those a binding reads or its literal has, null included, must be ones the target accepts, and a binding that can
give null must write a JSON body or a querystring of JSON content; a cursor that can be null needs a `null` end, and
each end value must be of a type the cursor reads. Literals that make a path segment whose every parameter they fill a
dot segment once encoded in their parameters' styles, such as `..` in the simple style, or the empty string in the
label style, are no path parameter values, reported at the segment's first literal binding, and a body target needs a
required body or one media type a call without `media_type` sends. A binding that writes the continuation's
target or another binding's, or a body or querystring member inside or around one, fails. An
offset's or page number's target must accept integers, a page number advances by a literal step, `has_more` must read
booleans, and `total` must read integers from the body or a header, never the status. A next URL must read strings, or
null with a `null` end, its end values must be strings, and `repeat_request_body` needs an operation with a body that
may be sent again; a Link continuation's header must be one the response declares, and `rel` one relation type, a
registered name such as `next` or an absolute URI. A next-URL or Link helper's binding that writes a path, query, or
querystring parameter, which the URL replaces, or the body without `repeat_request_body`, fails.
So does a cursor, position, or binding, a literal one included, that writes a cookie, the `Authorization`,
`Proxy-Authorization`, `Cookie`, or `Cookie2` header, or a header, query parameter, or querystring property at the
position of a declared security scheme: credentials are never written from what a server or a checkpoint gives. Every
cookie counts, declared as a scheme or not, because cookies commonly carry session state; this removes the cookie
cursors and cookie bindings earlier versions of the helpers wrote.
Helper names whose classes collide, such as `users.all_items` and `users_all.items`, fail.
Bindings that read the helper's input, request bodies other than JSON, and items or selector pointers that read
through a union or a map are not supported yet.

## Polling helpers

An enabled polling helper is generated at `client.protocols.<name>` on `Client` and `AsyncClient` alike. Its `start`
takes the `create` operation's parameters and its body as keywords, never field arguments, then `poll_options`,
and `options`, sends the create request, and returns a handle of the long-running operation (LRO) it created, an
`LroHandle`; the asyncio `start` is awaited:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.polling.helper -->
<!-- fmt: off -->

```python
    def start(
        self,
        *,
        body: models.JobRequest,
        media_type: Literal['application/json'] | None = None,
        poll_options: PollOptions | None = None,
        options: RequestOptions | None = None,
    ) -> LroHandle[GetReportResponse, GetJobResponse]:
        """Create the operation of POST /jobs and return the handle that polls it."""
        return start_operation(
            self._core,
            _plans.PLAN_0,
            (),
            body=body,
            media_type=media_type,
            poll_options=poll_options,
            options=options,
        )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.polling.helper -->

```python
from app.client import Client
from app.models import JobRequest


def run(job: JobRequest) -> None:
    with Client() as client, client.protocols.jobs.run.start(body=job) as handle:
        print(handle.status())
        print(handle.wait())
```

`LroHandle[T, P]` and `AsyncLroHandle[T, P]`, imported from `client.protocols`, hold one operation: `T` is the result
type and `P` the poll operation's response type. `status()` polls once and returns a `PollSnapshot[P]`; `wait()` polls
until the operation settles and returns its result. Both are coroutines on `AsyncLroHandle`. Each poll is its own call
of the `poll` operation, which writes each binding's value: what its selector reads from the create response for
`source: initial`, kept for the whole operation, or from the latest response, the create response and then each poll,
for `source: previous`, or a `literal`. A value is written as the server gave it, without its target's schema checks,
and a missing value, a header repeated for a single value, and read values that make a path segment `.` or `..` once
encoded, `%2E` in either case counting as `.`, raise `ProtocolDataError`. `progress` reports the polls sent, counting
none refused before sending.

### States and results

`start` sends the create request once, resent only as shared retries allow. A status in `accepted_statuses` returns a
pending handle. A status in `immediate_result.statuses` returns a handle that already holds the result, read from the
create response at the immediate result's selector; its `wait` returns the result without sending, and its `status`
raises `ConfigurationError` with the reason `invalid_state`, since it has no poll. Any other success status raises
`ProtocolDataError` with a `StatusSelector` location, and an error status raises the operation's HTTP error.

A poll's `state` selector must read a value equal to one of the `pending`, `succeeded`, `failed`, or `cancelled` values,
JSON type included; a missing state raises `ProtocolDataError`, and any other value raises it with the reason `type`
when no declared state has its JSON type and `value` otherwise. Success is never inferred. A failed or cancelled
operation makes `wait` raise `ProtocolDataError` with the reason `operation_failed` or `operation_cancelled`, the last
poll's decoded data as `data` and its response as `info`, and every later `wait` raises it again without sending;
`status` returns that poll. After a success, `wait` returns the result: the value an `inline` result's selector reads
from the final poll, the response of the result `operation`, fetched once with its bindings, whose `previous` source is
the final poll, or None for `kind: none`. Later `status` and `wait` calls send nothing. A missing or null result in the
final poll raises `ProtocolDataError` and leaves the handle pending, so a later `status` or `wait` polls again and
raises the same error while the result stays missing; a missing or null immediate result fails `start`.

An error that settles nothing, such as a transport error, an HTTP error, a deadline, a cancellation, a limit, or a
`ProtocolDataError` of a poll, leaves the handle as it was, so a later `status` or `wait` polls again without a new
create request, and a failed result fetch is retried alone. A spent limit stays spent for the handle's session, though:
once `max_polls` is reached, every later poll raises `SessionLimitError` again before sending. `close()` or `aclose()`,
or leaving a `with` or `async with` block, stops only local polling; the remote operation goes on, and every later step
raises `ConfigurationError` with the reason `invalid_state`. Calling `status`, `wait`, `close`, or `aclose` while
another step runs raises it too; a block that ends with an error while another step runs leaves
the handle open and lets its own error propagate. `checkpoint()` and `cancel_remote()` are not steps: they run while
another thread or task is in `status` or `wait`, such as one sleeping until its next poll.

### Waits and server delays

The first poll waits until `interval` seconds after the create response's receipt, and each later one until the
interval after the last poll's; with `interval.retry_after_header`, a valid delay in that header, in seconds or as an
HTTP date, makes the wait longer, never shorter. The delay counts from the final response of a call, after any retries
inside it, so a retry's own delay is never added to the poll interval. A poll or a result fetch that fails with a
response, such as a `503` after its retries, sets the next wait from that response the same way before its error is
raised, and the next poll or fetch waits for it; the first result fetch is sent at once. `status` waits the same way.
An interval longer than `PollOptions.max_wait`, or not shorter than the session's `total_timeout`, could never be
waited out, so `start` raises `ConfigurationError` with the
`field_path` `("poll_options", "interval")` before sending the create request. A wait a server delay makes longer
than `max_wait`, or not shorter than the remaining budget derived from the session and call `total_timeout`, raises
`SessionLimitError` with the reason `wait` or `deadline`, the `required_wait`, and the `limit` before anything is sent;
the handle stays as it was. Async waits propagate native task cancellation unchanged. Once the client is
closed, every later `status` or `wait` that needs a poll or a result fetch raises `ConfigurationError` with the reason
`client_closed`. The handle's [checkpoint](#polling-checkpoints-and-resume) continues it after that
`SessionLimitError`.

### Polling limits and sessions

`start` and its handle are one session. The create call, every poll, and the result fetch are calls of their own, with
their own retries, total timeout, and idempotency key, and the session bounds all of them: a call's deadline is the
earlier of its own and the session's. Each limit comes from the call's options, then the helper's options in the client's
`helper_defaults`, then the default below:

| Limit | Default | None |
|---|---|---|
| `PollOptions.max_polls` | 1000 polls | Removes the limit |
| `PollOptions.interval` | The declared `interval.seconds`, 1 second by default | Not allowed |
| `PollOptions.max_wait` | 60 seconds | Removes the limit |
| `PollOptions.total_timeout` | 600 seconds from `start` | Removes the limit |

A poll past a limit raises `SessionLimitError` with the reason `polls` and the progress so far, before sending; the
handle's `checkpoint()` continues the operation. The options of `start` apply to
every call of the handle. They must not fix an idempotency key, and their extra headers and query must not name
a header or a query parameter a binding writes; `start` raises `ConfigurationError` before
sending, as it does for options of another type.

### Polling checkpoints and resume

`handle.checkpoint()` returns plain JSON without sending, on `LroHandle` and `AsyncLroHandle` alike, also after
`close`: the server's values the next request writes, never an SDK envelope. While another thread or task runs
`status` or `wait`, it returns the handle as the last poll that settled left it, never waiting for a step. A settled
operation, one that failed, was cancelled, or holds its result, including one that completed at once, has nothing left
to continue: its `checkpoint()` raises `ConfigurationError`. The helper's
`resume(state, *, poll_options=None, options=None)` is not awaited, even on `AsyncClient`, and
returns the handle type `start` returns, in a session of its own, without sending: it never creates the operation
again. A pending handle's `status` or `wait` sends its first poll at once; a handle whose result fetch is due fetches it
once in `wait`, and its `status` raises `ConfigurationError`, since it holds no poll. A checkpoint does not keep a
server's delay, so a caller resuming after a `SessionLimitError` with the reason `wait` or `deadline` waits out its
`required_wait` itself before polling.

```python
import json
import time

from app.client import Client
from app.client.errors import SessionLimitError
from app.models import JobRequest


def run(job: JobRequest) -> None:
    with Client() as client:
        helper = client.protocols.jobs.run
        handle = helper.start(body=job)
        saved = json.dumps(handle.checkpoint())
        print(helper.resume(json.loads(saved)).wait())
        handle = helper.start(body=job)
        try:
            handle.wait()
        except SessionLimitError as error:
            if error.reason == "wait" and error.required_wait is not None:
                time.sleep(error.required_wait)
            print(helper.resume(handle.checkpoint()).wait())
```

| Member | Value |
|---|---|
| `phase` | `"pending"`, or `"fetch"` when the result fetch is due |
| `bound` | While pending, the values the next poll writes, read from the create response or the last pending poll; while the fetch is due, the values it writes |
| `cancel` | While pending, the values a remote cancel writes |
| `seed` | While pending, the values the create response gave the result fetch's `initial` bindings |
| `expires_at` | The server's expiry an `expires_at` helper read, as `datetime.isoformat()` text, or null |

The create request, its body and idempotency key, polls, results, model objects, the session, its deadline, the
call's `options`, and anything its auth adds are never part of it. A resumed pending handle polls with the saved
values, and one whose fetch is due fetches the result with them. Polls count afresh against the resumed call's
`max_polls`, and the session's timeout and deadline start afresh. A literal binding sends the plan's value, never a
saved one.

`resume` checks the resumed call's options as `start` does, then the state, before returning:

| Rejected state | Exception |
|---|---|
| A value that is not JSON, or one that does not fit the helper: an unknown or missing member, an unknown phase, a due fetch of a helper without one, values of another count than the bindings, or an expiry `datetime.isoformat()` would spell differently | `ConfigurationError(field_path=("state",), reason="invalid_value")` |
| An expiry that has passed | `ConfigurationError(field_path=("state",), reason="expired")` |
| A dot segment (`.` or `..`) a saved value of the next poll or remote cancel would write to a path parameter | `ProtocolDataError`, as for a server's value |

Any other saved value, a result fetch's included, is checked and encoded when the request that writes it is built, as a server's value is, so a value that
cannot be sent, such as one with CR, LF, or NUL in a header, raises the call's encoding error from `status` or `wait`
before sending. A checkpoint holds no credential and binds to no auth; store it as the call's own data.

### Remote cancellation and expiry

A helper that declares `remote_cancel` generates a handle class of its own, a subclass of `LroHandle` or
`AsyncLroHandle`, which `start` and `resume` return. Only it has `cancel_remote()`, a coroutine on the asyncio handle,
which returns a `CancelReceipt[C]`, imported from `client.protocols`, where `C` is the cancel operation's response type;
helpers without `remote_cancel` have no such method:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.polling.handle -->
<!-- fmt: off -->

```python
class JobsTrackedHandle(LroHandle[models.Report, GetJobResponse]):
    """A handle of the jobs.tracked polling helper, which also cancels the operation with DELETE /jobs/{jobId}."""

    __slots__ = ()

    def cancel_remote(self) -> CancelReceipt[CancelJobResponse]:
        """Ask the server to cancel the operation; the handle keeps its last poll until it polls again."""
        return self._cancel_remote(_plans.CANCEL_5)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.polling.handle -->

`cancel_remote()` sends the cancel operation once, at once, as a call of the handle's session, writing its bindings'
values: what its selectors read from the create response for `source: initial`, or from the latest response, the
create response and then each pending poll, for `source: previous`. A missing value in one of those responses fails
it as a poll binding's does. The receipt is immutable, with read-only `data` and `response`. The request does not
settle the operation: the handle keeps its phase, its last poll, and the time of its next poll, and only the next
`status` or `wait` tells whether the operation was cancelled. It counts no poll, and an error leaves the handle as it
was. It runs while another thread or
task is in `status` or `wait`, so a waiting operation can be cancelled from elsewhere: it reads the values to send when
it starts, and the `wait` goes on until a poll tells it the operation settled. A settled operation raises
`ConfigurationError` with the reason `invalid_state`, and so does a closed handle, both without sending.
`close()` never sends the cancel request.

The concrete handle classes are not exported from `client.protocols`: use the type `start` and `resume` return, or
annotate a handle as `LroHandle[T, P]` or `AsyncLroHandle[T, P]`, which they subclass, without `cancel_remote`.

`expires_at` is a selector of the server's expiry of the operation, read once from the accepted create response: a
string giving an RFC 3339 date-time with an offset, where a leap second is the second after the one before it, or
an HTTP date, read as [`Retry-After` dates](python-client-reference.md#retries-and-operation-contracts) are. A missing, null, non-string, or unparsable value fails `start` with `ProtocolDataError` after the create
response, as a missing binding value does; the remote operation was created all the same, and nothing cancels it. The
expiry, in UTC, becomes the expiry of every checkpoint of the handle, so `resume` refuses them afterwards with
`ConfigurationError` with the reason `expired`; it does not stop a live handle from polling. Without `expires_at`,
checkpoints never expire, and no expiry is assumed. An immediate result has none.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.polling.tracked -->
<!-- fmt: off -->

```json
{
  "jobs.tracked": {
    "kind": "polling",
    "create": "/paths/~1jobs/post",
    "accepted_statuses": [202],
    "poll": "/paths/~1jobs~1{jobId}/get",
    "bindings": [
      {
        "target": {"in": "path", "name": "jobId"},
        "value": {"source": "initial", "selector": {"from": "body", "pointer": "/id"}}
      }
    ],
    "state": {"from": "body", "pointer": "/status"},
    "pending": ["queued", "running"],
    "succeeded": ["done"],
    "failed": ["failed"],
    "cancelled": ["cancelled"],
    "result": {
      "kind": "inline",
      "selector": {"from": "body", "pointer": "/result"},
      "schema": {"pointer": "/components/schemas/Report"}
    },
    "remote_cancel": {
      "operation": "/paths/~1jobs~1{jobId}/delete",
      "bindings": [
        {
          "target": {"in": "path", "name": "jobId"},
          "value": {"source": "previous", "selector": {"from": "body", "pointer": "/id"}}
        },
        {"target": {"in": "header", "name": "X-Reason"}, "value": {"literal": "requested"}}
      ]
    },
    "expires_at": {"from": "body", "pointer": "/expires"}
  }
}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.polling.tracked -->

### Polling generation checks

Each accepted and immediate status must select a success response of the `create` operation, and the `poll`
operation, like a result `operation`, must declare exactly one success response with one JSON media type and a schema,
read natively. The state, each binding's selector, and an inline result must read what the responses declare: a body
pointer a property of the response's model, through every accepted create response for `source: initial` and also the
poll's for `source: previous`, or a declared header. Each declared state must have a JSON type the state reads. The
JSON types a binding reads or its literal has must be ones its target accepts, literals that make a path segment `.` or
`..` once encoded are no path parameter values, and every required parameter and required body of the poll and result
operations must be written by a binding, and a body a binding writes needs a default media type, since a poll or a
result fetch names none. Two bindings writing the same target, or a body or querystring member inside or around
another's, fail. As for pagination, no binding of the poll or the result fetch writes
a credential position: a
cookie, the `Authorization`, `Proxy-Authorization`, `Cookie`, and `Cookie2` headers, or a header, query parameter, or
querystring property a security scheme of the package names. An inline or immediate result reads a body pointer whose
schema is the declared `schema`; an immediate result needs a result kind other than `none`, success responses of
`create` that are all one JSON model, and the type of the result. A `remote_cancel` operation must declare a success
response, and its bindings are checked as the poll's, against the same responses; `expires_at` must read strings from
every accepted create response. Bindings that read the helper's input, request bodies other than JSON written by a
binding, and pointers that read through a union or a map are not supported yet.

## Upload helpers

An enabled `resumable_upload` helper of the `offset` profile is generated at `client.protocols.<name>` on `Client`
and `AsyncClient` alike. Its `start` takes the upload source, then the `create` operation's parameters and its body as
keywords, never field arguments, without the parameter the helper writes the content's size to, then
`upload_options` and `options`; `resume` takes the source and a checkpoint. Both are coroutines on
`AsyncClient`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.uploads.helper -->
<!-- fmt: off -->

```python
    def start(
        self,
        source: UploadSource,
        *,
        Tus_Resumable: str,
        X_Name: str | UNSET = UNSET,
        upload_options: UploadOptions | None = None,
        options: RequestOptions | None = None,
    ) -> UploadHandle[None]:
        """Measure the source, create the upload of POST /files, and return its handle."""
        return start_upload(
            self._core,
            _plans.PLAN_0,
            source,
            (Tus_Resumable, X_Name),
            upload_options=upload_options,
            options=options,
        )

    def resume(
        self,
        source: UploadSource,
        state: JSONValue,
        *,
        upload_options: UploadOptions | None = None,
        options: RequestOptions | None = None,
    ) -> UploadHandle[None]:
        """Check a checkpoint and the source size, then continue from the server offset."""
        return resume_upload(
            self._core,
            _plans.PLAN_0,
            source,
            state,
            upload_options=upload_options,
            options=options,
        )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.uploads.helper -->

```python
from app.client import Client

with Client() as client, open("video.mp4", "rb") as video:
    upload = client.protocols.files.upload
    handle = upload.start(video, Tus_Resumable="1.0.0")
    print(handle.advance())
    state = handle.checkpoint()
    handle.run()
```

`UploadHandle[T]` and `AsyncUploadHandle[T]`, imported from `client.protocols`, hold one upload: `T` is `None` for an
upload completed by length and the completion operation's response type otherwise. `advance()` appends one chunk, or
completes the upload once the server holds every byte, and returns an `UploadProgress`; `run()` appends every
remaining chunk, completes the upload, and returns its result. Both are coroutines on `AsyncUploadHandle`. Once
complete, `advance` returns the progress and `run` the kept result without sending. `checkpoint()` returns plain JSON
at any time before the upload completes, even while another thread or task steps the handle, and sends
nothing; a complete upload has nothing to resume, so its `checkpoint()` raises `ConfigurationError` with the reason
`invalid_state`.

### Sources

A source is `bytes`, a `bytearray`, a `memoryview`, or a seekable binary file, such as one `open(path, "rb")` returns
or an `io.BytesIO`; `UploadSource` names that union. `Client` and `AsyncClient` take the same sources. A file's content
runs from its position when `start` or `resume` is called to its end, and the call measures its size by seeking to
the end, without reading it. A file that cannot seek, an iterable, an iterator, or an asyncio stream raises
`ConfigurationError` with `field_path=("source",)` and the reason `wrong_capability` before anything is sent; send it
as an ordinary upload. A file whose `read`, `seek`, or `tell` gives anything but bytes and integers, such as a text
file or an asyncio file, raises it too. Sources are borrowed and never closed by the client,
and nothing is ever spooled to disk.

Each append seeks to the confirmed offset and reads the rest of its chunk into one buffer, synchronously on both
clients; the last chunk is read with one byte more. Content shorter or longer than the size measured at `start` raises
`ConfigurationError` with `field_path=("source",)` and the reason `source_changed`, and the handle sends nothing more:
every later step raises `ConfigurationError` with the reason `invalid_state`, though `checkpoint()` still works. The
content is not hashed, so a change that keeps its size is not found: keep it unchanged while it is uploaded. The body is
sent from that buffer in 64 KiB slices, so an upload holds one chunk at a time besides fixed read buffers.

### Chunks, offsets, and recovery

A chunk is `UploadOptions.chunk_bytes`, 8 MiB by default; set it in `helper_defaults` or per call for a server that
takes another size. The offset profile sends one chunk at a time.

`start` sends the create request once, resent only as shared retries allow, with the content's size in the declared
`size` parameter, and reads every binding's `initial` value and the server's expiry from its response. The upload
starts at offset 0. Each append writes the confirmed offset into `offset`, the length of the bytes it sends into
`length` when declared, and their checksum into `checksum.target` when declared, and sends the rest of the chunk as the
body; a success response confirms the chunk. A checksum is the `md5`, `sha1`, `sha256`, or `sha512` digest of those
bytes, computed from the chunk's buffer as each append is built, in `base64` (the default) or `hex`, after the
algorithm's name and a space with `algorithm_prefix: true`, as the tus checksum extension spells it. An append is never sent
again by shared retries once it may have reached the server, even for an operation that is otherwise safe to retry:

| Append outcome | What follows |
|---|---|
| A success response | The chunk is confirmed |
| A transport error after it may have been sent | One probe, retried only as shared retries allow: an unchanged offset sends the range again as a new call, the chunk's end confirms it, and an offset inside it confirms its bytes before it only with `partial_commit: allowed`, the rest being sent next |
| A probe that fails with a transport error or an error status | `APIConnectionError` with the reason `delivery_unknown` and the probe's failure named in its notes; the handle's `checkpoint()` resumes it |
| Any other failure, a cancellation included | Raised; the next step probes the server's offset before it appends |

A probe's offset is a JSON integer, or a header of ASCII digits; a missing one raises `ProtocolDataError` with the
reason `missing`, a header repeated with `malformed`, and anything else with `type`, `null`, or `value`. An offset
below the confirmed one, past the content, past the chunk sent, or inside a chunk with `partial_commit: forbidden`
raises `ProtocolDataError` with the reason `inconsistent` and the remote offset's selector as `location`. A handle
`start` returned also refuses an offset past every byte it has sent; a handle `resume` returned cannot know what an
earlier session sent, so it accepts any offset up to the size.

An upload completed by `length` completes when the server holds every byte. A completion `operation` is sent once with
its bindings; its response is the result. A completion whose outcome is unknown is never sent again: it raises
`APIConnectionError` with the reason `delivery_unknown`, and so does every later step and every resume of its
checkpoint, without sending. That includes a completion answered with 502 or 504, which a gateway gives even when the
server behind it may have applied the completion. A completion answered with any other error status, such as a 503 with
`Retry-After`, did not apply, so the next step may send it again.

`close()` or `aclose()`, or leaving a `with` or `async with` block, stops only local uploading; the remote upload
stays, and every later step raises `ConfigurationError` with the reason `invalid_state`. Calling `advance`, `run`,
`close`, or `aclose` while another step runs raises it too.

### Upload checkpoints and resume

`checkpoint()` returns plain JSON: an object with the content's `size`, the `chunk` size, the `confirmed` offset, the
values the probe, the append, and the completion write (`bound`, three arrays), a completion of unknown outcome
(`phase` `unknown`, otherwise `uploading`), and the server's `expires_at`. It holds
no content, digest, result, credential, or security binding: a resumed upload sends with the resuming client's own
auth, as pagination checkpoints do. Errors carry no checkpoint; call the handle's `checkpoint()`.

`resume(source, state)` starts a new session and never creates the upload again. It checks the call's options, then the
checkpoint: a value that is not JSON or does not fit the helper raises `ConfigurationError(field_path=("state",))`, and
one past the server's expiry the reason `expired`. A checkpoint keeps its chunk size, which must not exceed the call's
`UploadOptions.chunk_bytes`, since an append holds one chunk in memory; it raises `ConfigurationError` whose
`field_path` names where that size came from: `("helper_defaults", "files.upload", "chunk_bytes")` for a helper
named `files.upload` when the client's `helper_defaults` set it and the call's `upload_options` did not, else
`("upload_options", "chunk_bytes")`, which also covers the 8 MiB default. Then the saved values each call writes: a value that makes a path segment `.` or `..` raises
`ProtocolDataError`, as if a server gave it; any other saved value is encoded when its request is built. Then the
source: a one-shot input raises `ConfigurationError` with the reason `wrong_capability`, and a size other than the
checkpoint's the reason `source_changed`; the source is not read. A completion of unknown outcome raises
`APIConnectionError` with the reason `delivery_unknown` again without sending. Otherwise it probes the server's offset
once, which must not be below the saved one, and returns the handle.

A server's expiry is read once from the create response at `create.expires_at`, an RFC 3339 date-time with an offset or
an HTTP date; a missing, null, or unparsable value raises `ProtocolDataError` from `start`. It bounds only checkpoints
once it has passed: `resume` raises `ConfigurationError` with the reason `expired`; uploading goes on until the server
refuses.

### Upload limits and sessions

`start` and its handle are one session, and so are `resume` and its handle. The create call, every probe, every append,
and the completion are calls of their own, with their own retries, total timeout, and idempotency key, and the session
bounds all of them. Each limit comes from the call's options, then the helper's options in the client's
`helper_defaults`, then the default below:

| Limit | Default | None |
|---|---|---|
| `UploadOptions.chunk_bytes` | 8 MiB | Not allowed |
| `UploadOptions.total_timeout` | No limit | Removes the limit |

By default, an upload session has no total lifetime limit. If a finite `total_timeout` is configured, it runs from
`start` or `resume` for the whole life of the handle. A long upload stepped slowly may then need a larger timeout,
`UploadOptions(total_timeout=None)`, or a `resume` from a checkpoint, which starts a new session. The options must
not fix an idempotency key, and their extra headers and query must not name a header or a query parameter the helper
writes, the size included; `start` and `resume` raise `ConfigurationError` before reading or
sending, as they do for options of another type.

### Upload generation checks

The `create` operation must declare a success response, and each selector must read what every success response
declares: a server expiry reads strings and a remote offset integers, from a body pointer of the response's model or
a declared header, never the status. The `size`, `offset`, and `length` targets are path, query, or header parameters
that accept integers, never a credential position, and no two writes of the append share a target. The `append`
operation takes exactly one binary request media and declares a success response; no binding writes its body. The
`probe` declares a success response. Bindings read the create response with `source: initial`, or give a literal, and
fit their targets as polling bindings do; every required parameter of the probe, the append, and the completion must
be written. A completion operation declares exactly one JSON success response whose schema is its `result_schema`, and
a body its bindings write is JSON with a default media type. The `parts` profile, `abort`, `create.session_url`, and
bindings that read the previous response or the helper's input are not supported yet.

## SSE stream helpers

An enabled `sse` helper is generated at `client.protocols.<name>` on `Client` and `AsyncClient` alike, with one method,
`open`. It takes the operation's parameters and its body as keywords, never field arguments, then `stream_options`,
and `options`, sends the operation in a session of its own, and returns an `EventStream[T]`, or with
one `await` an `AsyncEventStream[T]`, once the response is a declared success of the helper's media type:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.streams.helper -->
<!-- fmt: off -->

```python
    def open(
        self,
        *,
        topic: str | UNSET = UNSET,
        Last_Event_ID: str | UNSET = UNSET,
        stream_options: StreamOptions | None = None,
        options: RequestOptions | None = None,
    ) -> EventStream[models.Message]:
        """Open the event stream of GET /events, returning once its response is a declared success."""
        return open_events(
            self._core,
            _plans.STREAM_0,
            (topic, Last_Event_ID),
            stream_options=stream_options,
            options=options,
        )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.streams.helper -->

```python
from app.client import Client

with Client() as client, client.protocols.events.typed.open() as stream:
    for event in stream:
        print(event.sequence, event.event_type, event.data)
```

`T` is the type of the helper's event schema, or the union of its mapped schemas' types, with `UnknownEvent` when
`unknown: raw` keeps unmapped events. Iterating a stream yields `StreamEvent[T]` records: `data`, the event's SSE
`event_type` (`message` when the event names none), `event_id`, the last ID the stream set or None when it set none or
an empty one, `retry_ms`, the last valid `retry` in milliseconds, `sequence`, numbering the dispatched events from 1,
and `raw_data`, the event's data text. `data()` iterates over the data of the same events and advances the same stream;
the asyncio `data()` is not awaited. Representations name no data, event ID, or raw data. `StreamEvent`,
`UnknownEvent`, `EventStream`, and `AsyncEventStream` are imported from `client.protocols`, in every package.

The response's status and `Content-Type` are checked before `open` returns: an error status raises the `APIStatusError`
subclass of its status, an undeclared status `APIStatusError` with the reason `unexpected_status`, and a body of another
media type, or none, `DecodeError` with the reason `unexpected_media_type`. A `204` the operation declares without a
body, by its own status, its range, or `default`, returns a stream that ends with no events whatever its completion, as
an `EventSource` stops on a `204`; a reopen or `resume` answered so ends the stream too, reading no binding value or
expiry from it, and an undeclared `204` still fails. Its acquisition retries like any call. A
stream then reads only the bytes its next event needs and owns the response until it ends, fails, or closes: close it
with `with`, `async with`, `close()`, or `aclose()`, since leaving a loop early releases nothing. One consumer reads a
stream at a time: a step, or a close, while another step runs raises `ConfigurationError` with the reason
`invalid_state`, and so does every step after a failure or `close()`; after its end every step stops. Streams own their
native response until it ends or the caller closes it. Close each stream explicitly before closing an owning root; a
borrowed native client retains its caller's lifetime.

### Framing and events

HTTPX2's `EventSource` parses the body as the WHATWG event-stream interpretation reads it: CR, LF, and CRLF end lines,
including a CRLF split between reads, lines starting with `:` are comments, `data` lines join with LF, `event` names
the type, an `id` containing NUL is ignored, and a blank line dispatches an event. The body is decoded as UTF-8 without
a leading byte order mark, whatever charset it declares, and invalid UTF-8 decodes to replacement characters. An event
without data is not delivered, though its `id` and `retry` still count; a `retry` that is negative or of more than 18
digits is ignored. An event over HTTPX2's event size limit, 1 MiB, raises `ProtocolDataError` with the reason
`too_large` and HTTPX2's `SSEError` as its `cause`. Each event's data is JSON converted to its schema's type through its
converter; data that is not JSON, or that the type refuses, raises `DecodeError` with the `location`
`("event", sequence)`, or `("event", sequence, pointer)` where a member is at fault, and at most 64 KiB of the data as
`body_bytes`.

An event schema mapping is chosen by the event's SSE type with `discriminator: {from: event_type}`, or by the string a
body pointer reads from the JSON data with `{from: body, pointer}`; a missing, null, or non-string body discriminator,
and an unmapped one without `unknown: raw`, raise `DecodeError`. An `error_events` key raises `ProtocolDataError` with
the reason `error_event` and the error schema's decoded `data` instead of yielding the event.

The stream ends as its `completion` declares: at the end of the body for `eof`, or at the event whose raw data equals a
`sentinel` value or whose SSE type is the `event_type` value; neither terminal event is decoded or yielded, and the
response is released. A body that ends before a sentinel or terminal type raises `StreamInterruptedError` with the
reason `eof`; an event the body ends in the middle of is discarded, as the event-stream interpretation discards it,
so under `eof` the stream simply ends and `incomplete_eof` cannot trigger a reconnect there. A connection that breaks
while the body is read raises `StreamInterruptedError` with the reason `transport` and the transport failure as its
`cause`. `sequence` is the last event delivered.

### Stream limits and sessions

`open` is one session holding one logical call. An optional total timeout bounds attempts while acquiring the
response. Native read timeouts bound idle I/O while reading the stream, and a helper session's optional total timeout
is checked before the next step. Decoding and cleanup preserve fully received results after a request budget expires.
Each limit comes from the call's options, then the helper's options in the client's `helper_defaults`, then the
default below:

| Limit | Default | None |
|---|---|---|
| `StreamOptions.idle_timeout` | The native read timeout | No idle limit |
| `StreamOptions.total_timeout` | None | No session deadline |
| `StreamOptions.reconnect` | False | Not allowed |
| `StreamOptions.max_reconnects` | 5 reconnections, counted across resumes; 0 allows none | Removes the limit |
| `StreamOptions.max_reconnect_wait` | 60 seconds | No wait limit |

Only a helper that declares `resume` reconnects: for any other, `StreamOptions(reconnect=True)` raises
`ConfigurationError` with the reason `missing_metadata`. Options of another type raise `ConfigurationError`.

### Checkpoints, resume, and reconnection

A helper whose metadata enables `resume` names the cursor of its events, `cursor: event_id` for the SSE event ID or a
`{from: body, pointer}` selector for a value in each event's JSON data, the request target its reopen writes it to, the
`reopen_operation`, and `delivery: at_least_once`. A body cursor also says what a missing value does, `missing:
inherit` keeping the cursor before or `error`, and what null does, `null: clear` or `error`. `bindings` write values
into the reopen request, read from the open response for `initial` or the latest open or reopen response for
`previous`, and `expires_at` reads the server's expiry from a header of the open response:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.streams.resume-json -->
<!-- fmt: off -->

```json
{
  "events.live": {
    "kind": "sse",
    "operation": "/paths/~1events/get",
    "media": "text/event-stream",
    "event_schema": {"pointer": "/components/schemas/Message"},
    "completion": {"kind": "eof"},
    "resume": {
      "enabled": true,
      "cursor": "event_id",
      "write": {"in": "header", "name": "Last-Event-ID"},
      "reopen_operation": "/paths/~1events/get",
      "delivery": "at_least_once"
    }
  },
  "events.tracked": {
    "kind": "sse",
    "operation": "/paths/~1events/get",
    "media": "text/event-stream",
    "event_schema": {
      "discriminator": {"from": "event_type"},
      "mapping": {"created": {"pointer": "/components/schemas/Created"}}
    },
    "unknown": "raw",
    "error_events": {"error": {"pointer": "/components/schemas/StreamError"}},
    "completion": {"kind": "event_type", "value": "done"},
    "resume": {
      "enabled": true,
      "cursor": "event_id",
      "write": {"in": "header", "name": "Last-Event-ID"},
      "reopen_operation": "/paths/~1streams~1{streamId}/get",
      "delivery": "at_least_once",
      "bindings": [
        {
          "target": {"in": "path", "name": "streamId"},
          "value": {"source": "initial", "selector": {"from": "header", "name": "X-Stream-Id"}}
        },
        {
          "target": {"in": "query", "name": "token"},
          "value": {"source": "previous", "selector": {"from": "header", "name": "X-Resume-Token"}}
        },
        {"target": {"in": "query", "name": "mode"}, "value": {"literal": "resume"}}
      ],
      "reconnect_on": ["transport_interruption", "incomplete_eof"],
      "expires_at": {"from": "header", "name": "X-Stream-Expires"}
    }
  }
}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.streams.resume-json -->

The helper then also has `resume`, which takes a checkpoint and the options `open` takes; when the reopen operation is
the helper's own, it also takes the operation's parameters and body again, as pagination's `resume` does. The asyncio
one is awaited once and returns the stream:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.streams.resume -->
<!-- fmt: off -->

```python
    def resume(
        self,
        state: JSONValue,
        *,
        criteria: dict[str, str] | UNSET = UNSET,
        body: models.FeedQuery,
        media_type: Literal['application/json'] | None = None,
        stream_options: StreamOptions | None = None,
        options: RequestOptions | None = None,
    ) -> EventStream[models.Tick]:
        """Reopen the event stream after a checkpoint's cursor, returning once its response is a declared success."""
        return resume_events(
            self._core,
            _plans.STREAM_0,
            state,
            (criteria,),
            body=body,
            media_type=media_type,
            stream_options=stream_options,
            options=options,
        )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.streams.resume -->

```python
import json
from pathlib import Path

from app.client import Client

saved = Path("events.checkpoint")
with Client() as client, client.protocols.events.live.open() as stream:
    for event in stream:
        print(event.data)
        saved.write_text(json.dumps(stream.checkpoint()))
with Client() as client, client.protocols.events.live.resume(json.loads(saved.read_text())) as stream:
    for event in stream:
        print(event.data)
```

The cursor is that of the last event the stream returned, never of a terminal, error, refused, or cut event: an SSE
event without an `id` keeps the ID before, an empty `id` clears it, and a body cursor follows its `missing` and `null`
settings, raising `DecodeError` with the reason `missing` or `null` before the event under `error`. HTTPX2
reports an empty `id` and no `id` alike until a response sets one, so a reopened response's events keep the ID it
reopened after until the response sends a nonempty one. An unknown event kept raw gives its body cursor from its data
when the data is JSON. A cursor is never limited apart from its event.

`checkpoint()` sends nothing and works on an open, ended, failed, or closed stream once a cursor was delivered; before
that, and while another step runs, it raises `ConfigurationError` with the reason `invalid_state`, and on a stream of a
helper without resume metadata `ConfigurationError` with the reason `missing_metadata`. It returns plain JSON, an object
with the `cursor`, the `bound` values of the bindings, and the server's `expires_at` as ISO 8601 text or null, never the
caller's arguments, events, counts, `retry` times, responses, the session, the call's options, or what its auth adds.
Like pagination and polling checkpoints, it holds no credential and binds to no auth; store it as the call's own data.
Errors carry no checkpoint: call the stream's `checkpoint()`.

`resume` creates a session of its own and sends the reopen at once: the helper's own operation sends the arguments and
body the caller gives `resume`, another one sends only what is written, each binding's value first and then the cursor,
whose parameter is omitted once the cursor is cleared, so a cleared SSE cursor sends no `Last-Event-ID`. The request
then returns once its response is a declared success, as `open` does; sequences, reconnections, and the session's
deadline start afresh, and the reopen counts as no reconnection. Before sending it refuses a checkpoint that is not JSON
or does not fit the helper, such as a missing or extra member, an empty event ID, or an expiry of another form, with
`ConfigurationError(field_path=("state",))`, and an expired one with `ConfigurationError(field_path=("state",),
reason="expired")`. The cursor and the bindings' values are written as a server's are: a saved dot segment for a path
parameter raises `ProtocolDataError`, a value the reopen would send as a credential header or a security scheme's query
field, including a property of an exploded form or deepObject query parameter, raises `ConfigurationError` with the
reason `wrong_capability`, and one the request cannot encode, such as an event ID that ends in a space or is not
ASCII, which a header cannot carry, raises the request's `DecodeError`.

With `StreamOptions(reconnect=True)`, a stream that has delivered a cursor reopens itself within the same step after a
read-phase transport failure the shared retry classification retries, or a read timeout the call's own `timeout`
set rather than the stream's idle limit, which wins a tie; after an NDJSON line cut by the
end of the body or an end before the declared completion it does so only when `reconnect_on` lists `incomplete_eof`.
Each reopen is one more child call of the stream's session: its own retries, Retry-After included, follow the call's
retry options. Before a reopen the stream waits the retry backoff, and at least the last `retry` time the server sent,
in the session's deadline. When the backoff's cap or that `retry` time is longer than `max_reconnect_wait`, whatever the
jitter draws below the cap, or the wait is not shorter than the session's remaining time, the wait is not begun and the
interruption is raised. Running out of reconnections raises `SessionLimitError` with the reason `reconnects`,
never a normal end. A cursor a reconnection cannot encode, such as an event ID that is not ASCII, raises
`ProtocolDataError` with the reason `value` and the cursor's selector, or for an event ID the target it is written
to, as `location`, with the interruption as its context,
and a value it would send as a credential raises `ConfigurationError` with the reason `wrong_capability`. A decode,
size, remote, idle, or deadline failure, the declared end, a reopen answered with an error, and closing never reconnect.
Events the server sends again after a reopen are delivered again, numbered on: nothing removes duplicates. Every open
and reopen is its own request of the HTTP client, which its `event_hooks` see. Neither the headers and query of the
client, a view, or the call may name a header or query parameter a resuming helper's reopen writes, nor the call fix
an idempotency key.

### Stream generation checks

The helper's `media` must be `text/event-stream`, compared without case and with any parameters allowed, and a success
response of its operation must declare an event stream media type, which the helper then requests as declared. Each
event and error schema must exist. A body discriminator must name a declared property of each mapped and error schema
whose values can be strings, and an `event_type` completion cannot be a key of the event type mapping or the error
events.

A resumption is checked against its reopen operation, which must declare a success response of the helper's media type.
A cursor is never written to a cookie, a credential header, a security scheme's position, an exploded form object query
parameter declaring a property at such a position, or a path parameter, and one that can be cleared, an event ID or a
body cursor with `null: clear`, only to an optional header or query parameter; a body cursor must read a declared
property of an event schema, of every one under `missing: error`, whose types fit its target. Bindings are checked as
polling bindings are, reading only the headers and status of the stream responses, and a reopen with another operation
must write each of its required parameters and its body.

## NDJSON stream helpers

An enabled `ndjson` helper reads a body of newline-delimited JSON records, one JSON value a line, as the
[SSE stream helper](#sse-stream-helpers) reads events: it is generated at `client.protocols.<name>` with the same `open`
method and returns the same `EventStream[T]`, or `AsyncEventStream[T]`, so everything above about opening, iterating,
`data()`, closing, error events, limits, and sessions applies to it too, except what concerns SSE framing:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.ndjson.helper -->
<!-- fmt: off -->

```python
    def open(
        self,
        *,
        topic: str | UNSET = UNSET,
        stream_options: StreamOptions | None = None,
        options: RequestOptions | None = None,
    ) -> EventStream[models.Record]:
        """Open the NDJSON stream of GET /records, returning once its response is a declared success."""
        return open_events(
            self._core,
            _plans.STREAM_0,
            (topic,),
            stream_options=stream_options,
            options=options,
        )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.ndjson.helper -->

```python
from app.client import Client

with Client() as client, client.protocols.records.all.open() as stream:
    for record in stream.data():
        print(record.text)
```

```json
{
  "records.all": {
    "kind": "ndjson",
    "operation": "/paths/~1records/get",
    "media": "application/x-ndjson",
    "event_schema": {"pointer": "/components/schemas/Record"},
    "completion": {"kind": "eof"},
    "final_line": "require_newline"
  }
}
```

### Records

LF ends a line, and so does CRLF, whose CR is not part of the record; a CR alone does not end one. Each line is one
record, strict UTF-8 JSON decoded by the helper's schema, or by the schema a `{from: body, pointer}` discriminator maps
it to, the only discriminator NDJSON has. Every line is a record, so a blank or whitespace-only line, one that is not
UTF-8, a leading byte order mark, and anything else that is not JSON raise `DecodeError` with the reason
`malformed` and the `location` `("event", sequence)`; none is skipped. The error keeps at most the event limit or 64 KiB
of the line as `body_bytes`, which no message shows, and a line that is not UTF-8 has no `cause`.

A record yields a `StreamEvent` whose `event_type` is the empty string and whose `event_id` and `retry_ms` are None; an
`error_events` record raises `ProtocolDataError` with the reason `error_event`. A `sentinel` completion ends at the line
equal to its value, which is compared before JSON decoding and never yielded, so the value need not be JSON; a value
containing LF could never match, so it fails generation.

`final_line` says how the body may end. With `require_newline`, every record ends with a line end, and bytes after the
last one raise `StreamInterruptedError` with the reason `eof`. With `allow_eof`, those bytes are decoded as
the last record, a sentinel included; a body that ends with a line end ends the same way under both.

A line split over many reads is joined once its line end arrives, so it costs time linear in its length.

### NDJSON generation checks

The helper's `media` must be `application/x-ndjson`, `application/ndjson`, `application/jsonl`, `application/x-jsonl`,
`application/jsonlines`, or `application/x-jsonlines`, compared without case and with any parameters allowed, and a
success response of its operation must declare that media type, which the helper then requests as declared. The schema
and resumption checks are those of SSE helpers, and an NDJSON cursor is always a body pointer.

## WebSocket helpers

An enabled `websocket` helper is generated at `client.protocols.<name>` on `Client` and `AsyncClient` alike, with one
method, `connect`. Its channel is a GET operation, whose handshake request the helper sends: the operation gives the
URL, the parameters, the servers, and the security. `connect` takes the operation's parameters as keywords, then
`ws_options` and `options`. On `Client` it returns a `WebSocketSession[S, R]` once the server
accepted the handshake; `with` or `close()` closes it. On `AsyncClient` it returns an async context manager: `async
with` sends the handshake and enters an `AsyncWebSocketSession[S, R]`, which leaving the block closes:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.websocket.helper -->
<!-- fmt: off -->

```python
    def connect(
        self,
        *,
        room: str,
        since: int | UNSET = UNSET,
        ws_options: WSOptions | None = None,
        options: RequestOptions | None = None,
    ) -> WebSocketSession[models.ClientMessage, models.ServerMessage]:
        """Open the WebSocket of GET /rooms/{room}/socket, returning once its handshake got a valid 101."""
        return connect_socket(
            self._core,
            _plans.SOCKET_0,
            (room, since),
            ws_options=ws_options,
            options=options,
        )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.websocket.helper -->

```python
import asyncio

from app.client import AsyncClient, Client
from app.models import ClientMessage

with Client() as client, client.protocols.rooms.chat.connect(room="lobby") as session:
    session.send(ClientMessage(text="hi"))
    for message in session:
        print(message.sequence, message.data)


async def chat() -> None:
    async with AsyncClient() as client, client.protocols.rooms.chat.connect(room="lobby") as session:
        await session.send(ClientMessage(text="hi"))
        async for message in session:
            print(message.sequence, message.data)


asyncio.run(chat())
```

```json
{
  "rooms.chat": {
    "kind": "websocket",
    "operation": "/paths/~1rooms~1{room}~1socket/get",
    "subprotocols": ["chat.v2", "chat.v1"],
    "send": {"codec": "json", "schema": {"pointer": "/components/schemas/ClientMessage"}},
    "receive": {"codec": "json", "schema": {"pointer": "/components/schemas/ServerMessage"}}
  }
}
```

`send` and `receive` declare how the messages of each direction are coded: `codec: json` with a `schema`, whose value
is sent as compact UTF-8 JSON and received through the schema's codec, `codec: utf8` for `str` text, or
`codec: bytes`. `frame` is `text` or `binary`; it defaults to `text` for JSON and UTF-8 messages and to `binary` for
bytes, and only JSON messages may choose. `S` is the send schema's argument type, its model type `T`, or `str` or
`bytes`, and `R` the received type; a union schema carries several message types. `subprotocols` lists the offered
subprotocols in order (`[]` by default). `enabled` defaults to `true`; a disabled helper generates nothing, as for every
helper kind. HTTPX2 WebSockets do not negotiate `permessage-deflate`, so the helper has no compression setting.

`WebSocketSession`, `AsyncWebSocketSession`, `Message`, `PingReceipt`, and `WSOptions` are imported from
`client.protocols`, and the WebSocket exceptions from `client.errors`. Sessions run on `httpx2.websockets`, so generation
prints `httpx2[ws]` among the packages to add for a package with WebSocket helpers; other packages never import it.

### Handshakes

The handshake is one logical call of the operation, with initial authentication and deadline, sent as
a GET with the upgrade headers through the client's HTTP client: its transport, proxy, TLS, and `event_hooks` apply
as to any call. Only a 101 response whose subprotocol the helper offered opens the session; HTTPX2 checks nothing else
of it, as its own WebSocket client does. Any other response is read up to its 64 KiB error prefix and raises the
`APIStatusError` subclass of its status, or `APIStatusError` with the reason `unexpected_status` for an undeclared
status, so 101 need not be declared. Received refusals are terminal, including redirects, which a handshake never
follows, and 401s; a refused upgrade never renews a token. Only an initial transport failure
proven unsent before session handover may use the call's existing retry policy. A handshake that may have reached
the server is never sent again.

When the helper offers subprotocols, the server must select one of them, or `connect` raises `APIConnectionError` with the
reason `negotiation_failed`; `session.subprotocol` is the selected one and `session.response` the 101 response.
Credentials are sent as the operation's security declares, only to the server's origin. Headers the handshake manages, such as `Upgrade`, `Connection`, and `Sec-WebSocket-*`, given through
request options or parameters raise `ConfigurationError` with the reason `managed` before anything is sent.

### Sessions

| Method | Behavior |
|---|---|
| `send(value)` | Encodes one message and sends it as one message of the declared frame |
| `receive()` | Returns the next `Message[R]`: `data`, `frame` (`text` or `binary`), `sequence` from 1, and `raw` bytes |
| Iteration | Yields messages until the server closes normally |
| `ping(payload=b"")` | Sends a ping of at most 125 bytes, a random one when empty, and returns a `PingReceipt` with the pong's `latency` in seconds |
| `close(code=1000, reason="")`, `aclose` | Closes with 1000, 1001, or a code from 3000 to 4999 and a reason of at most 123 UTF-8 bytes; repeats do nothing |
| `with` | Closes a synchronous session on exit; an asyncio session is the `async with` block of its `connect` |
| `progress` | The session's `messages_sent` and `messages_received` |

An HTTPX2 `WebSocketSession` or `AsyncWebSocketSession` carries the connection: it reads in the background, answers
pings, and sends keepalive pings. The session owns it until it closes or fails, but the connection belongs to the HTTP
client's pool. Closing a `Client` that created its HTTP client closes its open sessions first, as their `close()` does,
after which every step raises `ConfigurationError` with the reason `invalid_state`; close sessions before closing a
borrowed HTTP client, since closing a socket does not wake the session's reader on every platform. Closing an
`AsyncClient` closes the connections of its open sessions, whose next step then fails. One `receive` waits at a time:
another raises `ConfigurationError` with the reason `invalid_state`, while sends, which HTTPX2 writes one at a time, may
run beside it. Cancelling the task of an asyncio `receive`, as `asyncio.wait_for` does, leaves the session usable, since
HTTPX2 queues whole messages; a cancelled `send` or `ping` fails the session, since a message may be half written. An
`AsyncWebSocketSession` runs the HTTPX2 session in the task that entered its `connect` block, as HTTPX2's task group
must end in the task that started it, and closes it when the block ends; tasks the block starts may use and close it
meanwhile. A failure the block raises, even an exit such as `SystemExit`, leaves it unwrapped; a failure of HTTPX2's
background tasks cancels the block and leaves it as `APIConnectionError`. A received message of another frame kind, or
one that does not decode, raises `DecodeError` with the `location` `("message", sequence)` and at most 64 KiB of it as
`body_bytes` and closes the connection with 1002. A server's closure raises `WebSocketClosedError` with its `code`,
`reason`, and `clean`, which is true for 1000 and 1001, the closures that alone end iteration; the session answers it
with the same code and reason, and after it `receive`, `send`, and `ping` raise it again. A `send` or `ping` on a
connection that is already closing, before `receive` reported why, raises `WebSocketClosedError` without a code. After
any other failure, every step raises `ConfigurationError` with the reason `invalid_state`, as it does after `close()`.
Representations never show messages, URLs, headers, or close reasons.

### WebSocket limits

Each limit comes from the call's `ws_options`, then the helper's options in the client's `helper_defaults`, then the
default below. The session's optional total budget uses the client's `Clock`; native waits receive the
remaining duration as their timeout:

| Limit | Default | None |
|---|---|---|
| `WSOptions.open_timeout` | 5 seconds, also capped by the connect, read, write, and pool timeouts and the deadline | No open limit |
| `WSOptions.idle_timeout` | The native read timeout | No idle limit |
| `WSOptions.max_message_bytes` | HTTPX2's default (64 KiB in 2.13); a set value is passed as its `max_message_size_bytes` | Not allowed |
| `WSOptions.ping_interval`, `pong_timeout` | 20 seconds each, HTTPX2's keepalive settings; `pong_timeout` also bounds `ping()` | No keepalive pings |
| `WSOptions.total_timeout` | None | No session budget |

A message over `max_message_bytes`, or over HTTPX2's default while that is unset, raises `ProtocolDataError` with the
reason `too_large` after HTTPX2 closed the connection with 1009. A receive that waits longer than the idle timeout raises `APITimeoutError` with the reason
`phase_timeout` and closes with 1001, as does a ping whose pong does not arrive within the pong timeout; another
failure closes with 1011. A missed keepalive pong makes HTTPX2 close with 1011, and the next `receive` raises
`APIConnectionError`. The session deadline bounds every wait and raises `APITimeoutError` with
the reason `deadline_exceeded`. Messages are written whole by HTTPX2, without a timeout of their own; a send that may
have reached the server raises `APIConnectionError` with the reason `delivery_unknown`, closes the session, and is never
sent again. Received messages wait in HTTPX2's queue until they are read. Sessions never reconnect. Options of
another type raise `ConfigurationError`.

### WebSocket generation checks

The operation must be a GET without a request body, and each JSON message's schema must exist. Message definitions, frames, and subprotocol tokens are checked as the helper file is read.

## Cache helpers

An enabled `cache` helper fetches one GET operation through a private cache: it answers from a fresh
stored response without sending, revalidates a stale one with its `ETag` or `Last-Modified` validator, and otherwise
sends the request as an ordinary call. Nothing is cached for ordinary methods, and a client without a cache helper
keeps no cache state. The helper is generated at `client.protocols.<name>` on `Client` and `AsyncClient` alike:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.cache.json -->
<!-- fmt: off -->

```json
{
  "users.profile": {
    "kind": "cache",
    "operation": "/paths/~1users~1{userId}/get",
    "validator": "both",
    "authenticated": false,
    "vary_allowlist": ["Accept-Language"]
  }
}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.cache.json -->

| Setting | Meaning |
|---|---|
| `operation` | The GET operation the helper fetches. It takes no request body, and each cacheable status is a declared 2xx success with one JSON body |
| `validator` | `etag` revalidates with `If-None-Match` from `ETag`, `last_modified` with `If-Modified-Since` from `Last-Modified`, and `both` with `If-None-Match` when an `ETag` is stored and `If-Modified-Since` otherwise |
| `authenticated` | Whether the fetch carries credentials. It must match every call: a call that the auth, a credential or cookie header, or a security scheme's field authenticates needs `true`, and any other call `false` |
| `statuses` | The cacheable statuses, distinct, from 100 to 599 |
| `vary_allowlist` | The request headers a response's `Vary` may name; a response that varies on any other header, or on `*`, is not stored. The headers credentials travel in (`Authorization`, `Proxy-Authorization`, `Cookie`, `Cookie2`, and the declared security schemes' headers) are allowed as well, since the key covers them. Responses behind a CDN often vary on `Accept-Encoding`: allow it to store them |

`fetch` takes the operation's parameters as keywords, then `cache_options` and `options`, and returns a `CacheResult`.
With asyncio, `fetch` is a coroutine:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.cache.helper -->
<!-- fmt: off -->

```python
    def fetch(
        self,
        *,
        fields: str | UNSET = UNSET,
        Accept_Language: str | UNSET = UNSET,
        userId: int,
        cache_options: CacheOptions | None = None,
        options: RequestOptions | None = None,
    ) -> CacheResult[GetUserResponse]:
        """Fetch GET /users/{userId} through the helper's cache, revalidating a stale entry."""
        return fetch(
            self._core,
            _plans.PLAN_0,
            (fields, Accept_Language, userId),
            cache_options=cache_options,
            options=options,
        )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.cache.helper -->

A helper keeps its entries in the store the client's `cache_stores` lends it under its name. A helper without one
uses a `MemoryCacheStore` (`AsyncMemoryCacheStore` on `AsyncClient`) of 128 entries, which the root client creates at
the first such fetch and shares with its views and its other cache helpers without a store; another client never
shares it. The client checks the lent stores when it is constructed: a name that is no cache helper of the package
fails with `unknown_field`, and an object without the three store methods, or whose methods are coroutines for a
`Client` or plain functions for an `AsyncClient`, with `wrong_capability`. The client borrows a lent store: it never
closes one.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.cache.usage -->
<!-- fmt: off -->

```python
def cached_client() -> Client:
    """Lend a bounded memory store to the users.profile helper, which keeps its entries there."""
    store = MemoryCacheStore(max_entries=1000)
    return Client(cache_stores={"users.profile": store}, helper_defaults={"users.profile": CacheOptions(max_ttl=60)})
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.cache.usage -->

### Results and freshness

`CacheResult[T]` is immutable: `data: T`, the decoded body; `source`, `network` for a response the network sent,
`fresh_cache` for a fresh stored response answered without sending, or `revalidated` for a stored response a 304
confirmed; `response: ResponseInfo`; and `network_status`, the status the network returned, 304 for a revalidation and
`None` for a fresh answer. A fresh answer's `response` has every count 0 and the elapsed time of the
lookup and decoding; a revalidation's has the 304 call's counts and elapsed time, with the stored status and
the merged headers, request id, and content type. A stored body is decoded again on every use, so callers never share a
model object. A fresh answer sends nothing, so the HTTP client's `event_hooks` see no request; a network fetch is an
ordinary request.

An entry is fresh while its age is below its freshness lifetime and below `CacheOptions.max_ttl`. The lifetime is the
response's `Cache-Control: max-age`, else `Expires` minus `Date`, else 0; the age follows RFC 9111 from `Age`, `Date`,
and the times of the request and the response. There is no heuristic freshness and no stale-on-error. A response's
`no-cache` makes every use revalidate. A fetch's own `Cache-Control` may say `no-cache` (revalidate), `no-store` (no
stored response is read or written), or `max-age=N` (use a stored response only up to that age); any other directive,
and a `Range`, `If-Range`, `If-Match`, or `If-Unmodified-Since` header, raises `ConfigurationError` before
anything is looked up.

A stale entry is revalidated with its validator as `validator` declares; a fetch that gives `If-None-Match` or
`If-Modified-Since` itself sends it once, and raises `ConfigurationError` with the reason `binding_mismatch` and the
header's name as `field_path` before sending when a usable entry has another validator or the header is given more than
once. A 304 updates the entry's headers, except `Content-Type`, `Content-Encoding`, `Content-Length`, and hop-by-hop
fields, and its freshness. A 304 without a usable entry, after a redirect, or with an `ETag` or `Last-Modified` other
than the entry's raises `ProtocolDataError` with the reason `inconsistent`; no request is sent again. A validator
that is not [header text](python-client-reference.md#model-codecs), such as an entity tag with non-ASCII text, is never sent back, since no
client can write it as every server reads it: it counts as no validator, so its entry is fetched again without a
condition, and a response that is not fresh is not stored for it.

### Storing and keys

A response is stored only when its status is cacheable, it came without a redirect, it has no `Set-Cookie`, its
`Cache-Control` has only RFC 9111 directives (`s-maxage` is ignored) and no `no-store`, its `Vary` names only
allowlisted headers, and it is fresh or can be revalidated. The body's size is not limited: whatever HTTPX2 returned is
stored. A response that cannot be stored removes the entry it supersedes, and errors and decoding failures store
nothing and keep the entry. Entries hold the body after content decoding and the headers without `Content-Encoding` or
hop-by-hop fields.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.cache.keys -->
`fetch` returns a `CacheResult` whose `source` is `fresh_cache` for a fresh entry, answered without sending or call
events, `revalidated` for a stale entry a 304 confirmed, and `network` otherwise; a stored body is decoded again every
time. An entry is keyed by the method, the Accept header, and the identity the request is sent as: before the lookup,
the call's Auth, which is its own, its credentials', or else the HTTP client's, places credentials on a copy of the
request without sending it, and the key takes the URL with any query credentials, the values of the credential headers,
and every header the Auth added or changed. A callable credential is therefore called, and a token may be requested,
for the lookup as well as for the send. A response is stored only when the request it answered was sent as the same
identity, so a rotated or one-time credential, a timestamped signature, or a renewed token is never stored and never
answers another identity. An entry is selected by the request headers its `Vary` names and those the client's, views',
or call's headers name or a declared parameter fills. A request carrying credentials needs a helper declared
authenticated and an anonymous one a helper declared anonymous; anything else raises `ConfigurationError` with the
reason `binding_mismatch`. Credentials a request does not carry, such as a client certificate or an authenticating
transport, are not in the key: give such a client a store of its own.
Freshness comes from `max-age` or `Expires` only, capped by `max_ttl`; a stale entry is revalidated with its validator,
and a 304 without a usable entry raises `ProtocolDataError`. A validator a header cannot carry as ASCII text is never
sent, and its entry is fetched again without it. A response is stored only when its status is cacheable, it
came without a redirect, Set-Cookie, `no-store`, or an unsupported Cache-Control directive, and its `Vary` names only
allowlisted headers; otherwise it removes the entry it supersedes. Store failures raise `SDKError` with the reason
`store_failed` and never resend a request.
The store keeps one representation per key. A Vary mismatch is a miss; a successful cacheable response replaces it.
Vary stores plain ordered header values in private process memory, excluding credential headers and cookies.
Memory stores are bounded by entry count (128 by default), with reads and writes marking a key recently used.
Concurrent custom-store writes use last-completing replacement.
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.cache.keys -->

!!! warning "Credentials the cache cannot see"
    The key covers the credentials a request carries when the call's Auth places them. Credentials the SDK never
    sees, such as a client certificate, or a borrowed HTTP client's authenticating transport or event hooks, make
    requests with different identities share keys: give each such identity a client of its own, or a store of its
    own.

### Stores

`CacheStore` and `AsyncCacheStore` provide `get(key) -> CacheEntry | None`, `set(key, entry) -> None`, and
`delete(key) -> None`, using byte keys. Each key holds one representation. A Vary mismatch is a miss, and a successful
cacheable response replaces the representation. Concurrent custom-store writes use last-completing replacement.
A store exception or a result of another type raises `SDKError` with the reason `store_failed` and the exception as
`cause`; the request is never sent again for it.

`CacheEntry` has `vary`, `vary_values`, `status_code`, `headers`, `body`, `request_time`, `response_time`, `stored_at`,
`freshness_seconds`, `initial_age_seconds`, and `schema_fingerprint`. Plain Vary values preserve each named header's
ordered values, including the distinction between a missing header and an empty value. Credential headers and cookies
are excluded from these values and isolated by the opaque cache key. Values stay in private process memory and the
entry's representation names only its status. A mismatched fingerprint or status cannot serve a fetch or a 304.

`MemoryCacheStore(max_entries=128)` and `AsyncMemoryCacheStore(max_entries=128)` bound entries by count. Reads and
writes mark a key recently used, replacement keeps the count unchanged, and adding a key evicts the least recently
used key when needed. Deletion is idempotent. Freshness and revalidation use the fetching client's clock.

### Cache generation checks

The operation must be a GET without a request body; other methods fail, and HEAD is not
supported yet. Each cacheable status must be a declared 2xx success with one natively decoded JSON body, a helper
declared anonymous cannot fetch an operation that requires credentials.

## Webhook verification helpers

An enabled `webhook` helper generates the module `client.webhooks.<name>`, where each dotted part of the helper's name is a
package or the module. It verifies one received delivery, with a builtin `standard_webhooks`, `stripe_style`, `body_hmac`, `ed25519`, or
`rsa-pss-sha256` signature or through your verifier for an [`adapter` signature](#adapter-signatures), and decodes its
JSON event; a helper whose signature is [`none`](#unsigned-webhooks) only decodes. It creates no client, server, or
route. The key types of builtin signatures are in `client.webhooks.keys`, which exists only when a helper has a builtin
signature and whose name a helper cannot take, and a package exists only when at least one webhook helper is enabled.
With the package `app.client` and the `standard.message` helper below:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.usage -->
<!-- fmt: off -->

```python
def receive(raw_body: bytes, headers: list[tuple[str, str]], secret: bytes) -> Message:
    """Verify one delivery with the active key, return its event."""
    keys = KeySet(keys=(HmacKey(id="2026-09", secret=secret),))
    verified = message.verify(raw_body, headers, keys, now=datetime.now(timezone.utc))
    return verified.data
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.usage -->

The generated functions take the delivery and the keys positionally and everything else by keyword:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.helper -->
<!-- fmt: off -->

```python
def verify(
    raw_body: bytes,
    headers: Sequence[tuple[str, str]],
    keys: KeySet[HmacKey],
    *,
    now: datetime,
    options: WebhookOptions | None = None,
) -> VerifiedWebhook[models.Message]:
    """Verify a delivery and decode its event.

    Deliveries outside the timestamp window are rejected.
    Verification retains no delivery state; deduplicate in your application using delivery_id when present.
    """
    return verify_webhook(
        _PLAN,
        raw_body,
        headers,
        keys,
        now=now,
        options=options,
    )
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.helper -->

`verify(raw_body, headers, keys, *, now, options=None)` returns `VerifiedWebhook[Event]`, where `Event` is the
event schema's model type. `async def verify_async(...)` takes the same arguments and returns the same facts.
`raw_body` is the exact received `bytes`, `headers` a list or tuple of `(name, value)` string pairs in received order,
and `now` an aware datetime. `HmacKey(*, id: str, secret: bytes)` passes the secret to HMAC unchanged; the id is a
nonempty string without NUL, CR, or LF, the secret must be `bytes`, and its representation names the id only. Keys
cannot be changed, copied into new objects, or pickled.

### Public-key signatures

An `ed25519` helper takes `KeySet[Ed25519Key]` and an `rsa-pss-sha256` helper `KeySet[RSAPSSKey]`, where
`Ed25519Key(*, id: str, public_key: Ed25519PublicKey)` and `RSAPSSKey(*, id: str, public_key: RSAPublicKey)` wrap the
public key classes of [cryptography](https://cryptography.io/). `client.webhooks.keys` exports only the key types of the
selected signature kinds, and only these key types and their helpers import cryptography, so `client`, `client.protocols`,
and HMAC helpers import without it. A package with such a helper lists `cryptography>=50.0.0` among its dependencies,
and generation prints it in the `uv add` hint. Load the key with cryptography yourself, for example:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.public-keys -->
<!-- fmt: off -->

```python
def keys(raw_key: bytes, modulus: int) -> tuple[KeySet[Ed25519Key], KeySet[RSAPSSKey]]:
    """Wrap an Ed25519 public key from its raw bytes and an RSA public key from its numbers."""
    ed25519_key = Ed25519Key(id="active", public_key=Ed25519PublicKey.from_public_bytes(raw_key))
    rsa_key = RSAPSSKey(id="rsa-2048", public_key=RSAPublicNumbers(65537, modulus).public_key())
    return KeySet(keys=(ed25519_key,)), KeySet(keys=(rsa_key,))
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.public-keys -->

A key keeps the public key object it was given and uses it only to verify: it is never copied, serialized, compared, or
shown, and a private key, `bytes`, PEM or DER text, or a key of the other kind raises `TypeError` naming only the
expected class. The key's own class must derive from the cryptography class, so an object that only claims that class is
refused, while a class registered with it is accepted: the application supplies its keys. The SDK never derives a public
key from a private one. An Ed25519 signature is the raw 64-byte signature, and a decoded signature of another length is
`malformed_signature`. RSA-PSS uses SHA-256, MGF1 with SHA-256, and a 32-byte salt; each key decides its signature size,
so keys of different sizes can share a key set during rotation, and a signature of the wrong size for a key is
`invalid_signature` for that key. Only cryptography's `InvalidSignature` moves on to the next signature or key;
`UnsupportedAlgorithm` raises `ConfigurationError` with `reason="wrong_capability"` and the key's
`("keys", "<index>")`, and any other error, including cancellation, propagates unchanged. The signature settings are the
same as for HMAC:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.public-keys-json -->
<!-- fmt: off -->

```json
{
  "rfc8032.ed25519": {
    "kind": "webhook",
    "event_schema": {"pointer": "/components/schemas/Push"},
    "signature": {"kind": "ed25519", "header": "X-Signature", "encoding": "hex", "prefix": ""}
  },
  "wycheproof.rsa": {
    "kind": "webhook",
    "event_schema": {"pointer": "/components/schemas/Count"},
    "signature": {"kind": "rsa-pss-sha256", "header": "X-Signature", "encoding": "hex", "prefix": ""}
  }
}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.public-keys-json -->

### Signature settings

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.json -->
<!-- fmt: off -->

```json
{
  "standard.message": {
    "kind": "webhook",
    "event_schema": {"pointer": "/components/schemas/Message"},
    "signature": {"kind": "standard_webhooks"}
  }
}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.json -->

| Signature kind | Authenticated bytes and configuration |
|---|---|
| `standard_webhooks` | `webhook-id.webhook-timestamp.body`; fixed HMAC-SHA256, `webhook-signature` with space-separated `v1,<base64>` signatures |
| `stripe_style` | `timestamp.body`; one decimal `t` and hex `v1` candidates in a comma-separated header, default `Stripe-Signature` |
| `body_hmac` | Raw body; required `header`, `algorithm` (`hmac-sha256` or `hmac-sha512`, default SHA256), `encoding` (`hex` or `base64`, default hex), and optional `prefix` (default empty) |
| `ed25519`, `rsa-pss-sha256` | Raw body; required `header`, optional `encoding` (`hex`, `base64`, or `base64url`, default hex) and `prefix` (default empty) |

Standard Webhooks returns an authenticated delivery id and timestamp. Stripe-style signatures return the timestamp
and no delivery id. Body HMAC and public-key signatures return neither fact. Other signature formats use an adapter.
Each helper's `event_schema` selects a webhook or callback JSON request-body model, or an [event mapping](#event-mappings).
Header names are case insensitive; prefixes match exactly. Hex accepts either case, base64 requires padding, and
public-key base64url allows optional padding.

Invalid configuration is rejected during generation.

A header value is read as ASCII; a scheme that signs in any way the presets cannot describe needs an
[adapter signature](#adapter-signatures).

### Event mappings

Instead of one schema reference, `event_schema` can map the type name a body member holds to each event's schema, as SSE
and NDJSON helpers do, with a body discriminator only. The helper's event type is the union of the mapped models, and
each mapped schema must be a JSON request body of a webhook or callback operation. After verification, the body is
parsed once, the member the RFC 6901 `pointer` names selects the event's model, and the event decodes with it. The
member must be a string equal to a mapped name, compared exactly; otherwise decoding raises `ProtocolDataError` with
`location=BodySelector(pointer=...)` and the reason `missing` for an absent member, `null`, `type` for another JSON
type, or `value` for an unknown name. There is no `unknown` setting for webhooks.

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.adapter-json -->
<!-- fmt: off -->

```json
{
  "stripe.event": {
    "kind": "webhook",
    "event_schema": {
      "discriminator": {"from": "body", "pointer": "/type"},
      "mapping": {
        "invoice.paid": {"pointer": "/components/schemas/Invoice"},
        "invoice.updated": {"pointer": "/components/schemas/Invoice"},
        "customer.created": {"pointer": "/components/schemas/Customer"}
      }
    },
    "signature": {"kind": "adapter", "timestamp": "required", "delivery_id": "none"}
  },
  "unsigned.event": {
    "kind": "webhook",
    "event_schema": {
      "discriminator": {"from": "body", "pointer": "/meta/type"},
      "mapping": {
        "invoice.paid": {"pointer": "/components/schemas/Invoice"},
        "customer.created": {"pointer": "/components/schemas/Customer"}
      }
    },
    "signature": {"kind": "none"}
  }
}
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.adapter-json -->

### Adapter signatures

A signature `{kind: adapter, timestamp, delivery_id}` declares that your code verifies the signature: `timestamp` and
`delivery_id` are each `required` or `none`, and no other setting is read. The helper's functions are generic in the key
type and take a required `verifier: Verifier[K]` with `keys: KeySet[K]` of the same key type; `client.webhooks.keys` has
no key type for them. Write the verifier from the API's documentation, for example for a Stripe-style header:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.adapter -->
<!-- fmt: off -->

```python
@dataclass(frozen=True)
class StripeKey:
    """An application key: the SDK never reads its fields."""

    name: str
    secret: bytes = field(repr=False)


class StripeVerifier:
    """Verify `Stripe-Signature: t=<seconds>,v1=<hex>` over `<t>.<raw body>` with the first matching key."""

    def verify(
        self,
        raw_body: bytes,
        ordered_headers: tuple[tuple[str, str], ...],
        keys: KeySet[StripeKey],
        now: datetime,
        limits: ResolvedWebhookOptions,
    ) -> VerifiedSignature:
        """Return the signed timestamp and the matched key, or raise ProtocolDataError."""
        del now
        values = [value for name, value in ordered_headers if name.lower() == "stripe-signature"]
        items = [item.partition("=") for item in (values[0].split(",") if len(values) == 1 else ())]
        stamps = [value for scheme, _, value in items if scheme == "t"]
        encoded = [value for scheme, _, value in items if scheme == "v1"]
        if len(stamps) != 1 or not (stamps[0].isascii() and stamps[0].isdigit()) or not encoded:
            raise ProtocolDataError(reason="malformed_signature")
        if (count := len(encoded)) > limits.max_signatures:
            raise ProtocolDataError(reason="too_large")
        try:
            signatures = [bytes.fromhex(value) for value in encoded if value.isascii()]
        except ValueError:
            signatures = []
        if len(signatures) != count:
            raise ProtocolDataError(reason="malformed_signature")
        signed = stamps[0].encode() + b"." + raw_body
        for key in keys.keys:
            expected = hmac.new(key.secret, signed, "sha256").digest()
            if any(hmac.compare_digest(expected, signature) for signature in signatures):
                moment = datetime.fromtimestamp(int(stamps[0]), timezone.utc)
                return VerifiedSignature(delivery_id=None, timestamp=moment, matched_key_id=key.name)
        raise ProtocolDataError(reason="invalid_signature")


def receive_stripe(raw_body: bytes, headers: list[tuple[str, str]], secret: bytes) -> Invoice | Customer:
    """Verify one Stripe-style delivery with the application's verifier and return its mapped event."""
    keys = KeySet(keys=(StripeKey(name="2026-09", secret=secret),))
    verified = event.verify(raw_body, headers, keys, verifier=StripeVerifier(), now=datetime.now(timezone.utc))
    return verified.data
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.adapter -->

`verify_async` calls the same synchronous verifier, once. After the helper checks its arguments, including that
`verifier` has a callable `verify` (or `ConfigurationError` with `field_path=("verifier",)`), and the key-count
limit, it passes the exact body, the headers as a tuple of pairs in received order, the key set, `now`, and
the resolved limits; it never reads the keys. The verifier must authenticate the whole body and every fact it returns,
honor `max_signatures`, and raise `ProtocolDataError` with the reason `malformed_signature`, `invalid_signature`,
`missing_key`, or `timestamp_window` when verification fails; every error it raises, including cancellation, propagates
unchanged. Before decoding, the helper raises `ConfigurationError` with `field_path=("verifier",)` and the reason
`invalid_result`, without decoding, when the result is not a `VerifiedSignature` (an awaitable result is closed
unawaited), its `matched_key_id` is not a nonempty string, a `required` fact is missing, not a nonempty string delivery
id, or not an aware datetime, or a `none` fact is not `None`. A returned timestamp is then checked against the timestamp
window, as for builtin signatures.

### Unsigned webhooks

A signature `{kind: none}` declares that the API does not sign its deliveries; a helper without `signature` is refused,
so omitting it never means unsigned. The module has only `decode_unverified(raw_body) -> Event`, which refuses a body
that is not `bytes` (`ConfigurationError`) and decodes the event. Nothing authenticates who sent the delivery or
whether it was changed or replayed, and the result is the event alone, with no facts: treat it as untrusted input.

### Verification order and limits

A call checks `raw_body`, `headers`, `keys`, `now`, and `options`, then each builtin key's type and unique id. Invalid
arguments raise `ConfigurationError` with their field path. Key and signature counts are bounded by
`ProtocolDataError` with the reason `too_large`; the body and headers have no size limit here, so bound them in the web
server that receives the delivery. The helper checks signature syntax, timestamp tolerance when present, and
cryptographic authenticity before decoding the model. Decoding errors raise `ProtocolDataError`. An adapter checks that
`verifier.verify` is callable, then the key count, its returned facts, and the timestamp tolerance before decoding.
Errors keep no key, signature, header value, or body.

| Limit (`WebhookOptions`) | Default |
|---|---|
| `max_keys`, `max_signatures` | 8 |
| `past_tolerance`, `future_tolerance` | 300 and 30 seconds; 0 is allowed |

A failed verification raises `ProtocolDataError` with one of these reasons:

- `malformed_signature`: a missing, empty, misencoded, or wrong-size signature, an incorrect prefix, or a missing,
  repeated, or invalid required timestamp or delivery id. A malformed candidate fails even if another would verify.
- `timestamp_window`: the timestamp lies outside `now - past_tolerance` to `now + future_tolerance`, both inclusive,
  compared in exact microseconds.
- `missing_key`: the active key set is empty.
- `invalid_signature`: no active key verifies. Keys and signatures are tried in order; HMAC digests are compared in
  constant time, and public keys verify with cryptography. The first matching key supplies `matched_key_id`.

### Application deduplication

Verification retains no delivery state and returns every authenticated event independently. Use an authenticated
`delivery_id` to deduplicate in application storage when the scheme supplies one. Keep processing and deduplication
consistent with your application's transaction and acknowledgment rules.

### Webhook records and options

Generated packages expose webhook contracts from `client.protocols` and their exceptions from `client.errors`, where `client` is
the generated package name. These imports need no HTTP or cryptography library. The
[webhook verification helpers](#webhook-verification-helpers) verify HMAC, Ed25519, and RSA-PSS signatures, or call
your `Verifier[K]` for any other signature, and decode events; constructing a signature or event record yourself does not
verify received data.

All records below are immutable and keyword-only. `KeySet` retains the original tuple and key objects without
inspecting or copying the keys. Its representation excludes key material. `VerifiedWebhook` excludes event data
from its representation.

| Type | Fields |
|---|---|
| `OperationRef` | `pointer: str`, `document: str \| None = None` |
| `KeySet[K]` | `keys: tuple[K, ...]`; an empty tuple is valid; a list or another iterable raises `TypeError` |
| `VerifiedSignature` | `delivery_id: str \| None`, `timestamp: datetime \| None`, `matched_key_id: str`; all fields are required |
| `VerifiedWebhook[T]` | `data: T`, `delivery_id: str \| None`, `timestamp: datetime \| None`, `matched_key_id: str`; all fields are required |

`Verifier[K]` is a borrowed, synchronous protocol with this method:

```python
from datetime import datetime
from typing import Protocol, TypeVar

from app.client.protocols import KeySet, ResolvedWebhookOptions, VerifiedSignature

K = TypeVar("K")


class Verifier(Protocol[K]):
    def verify(
        self,
        raw_body: bytes,
        ordered_headers: tuple[tuple[str, str], ...],
        keys: KeySet[K],
        now: datetime,
        limits: ResolvedWebhookOptions,
    ) -> VerifiedSignature: ...
```

The key type is invariant and must match `KeySet[K]`. Implementations authenticate the complete received body
and every returned fact, perform no networking, and retain ownership of their application keys. The same
synchronous verifier contract applies to asynchronous consumers. [Adapter signatures](#adapter-signatures) describe how
a generated helper calls a verifier and checks its result.

`WebhookOptions` has the fields below. Every constructor default is `UNSET`, imported from `client.options`;
the effective values are the defaults in the table below, which the
[webhook verification helpers](#verification-order-and-limits) apply. `ResolvedWebhookOptions` has the same fields with
`UNSET` removed and every argument required. Both types are exported from `client.protocols`.
`ResolvedWebhookOptions` records limits already validated and resolved by the consuming helper. Helpers must
validate `WebhookOptions` before constructing this record and passing it to an application verifier.

| Field | Type | Effective default | Valid values |
|---|---|---|---|
| `max_keys` | `int \| UNSET` | `8` | Positive integer |
| `max_signatures` | `int \| UNSET` | `8` | Positive integer |
| `past_tolerance` | `float \| UNSET` | `300` seconds | Finite, nonnegative number |
| `future_tolerance` | `float \| UNSET` | `30` seconds | Finite, nonnegative number |

Options reject `None`, booleans, negative values, nonfinite durations, and zero count limits with
`ConfigurationError`. For example, `WebhookOptions(past_tolerance=0)` is valid, while
`WebhookOptions(max_keys=0)` is invalid. Verification retains no delivery state. Applications can deduplicate
using the authenticated `delivery_id` when a signature scheme supplies one.

Webhook exceptions have keyword-only constructors and the following additional fields:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.error-fields -->
| Exception | Direct base | Fields |
|---|---|---|
| `ConfigurationError` | `SDKError` | `field_path: tuple[str \| int, ...] = ()`, `reason: str = 'invalid_value'` |
| `ProtocolDataError` | `SDKError` | `reason: str = 'value'` |
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.webhooks.error-fields -->

All fields without a displayed default are required. They also accept the shared context fields
`helper_id: str | None = None`, `operation: OperationRef | None = None`, `info: ResponseInfo | None = None`, and
`cause: BaseException | None = None`, together with inherited SDK error fields. A failed webhook verification raises
`ProtocolDataError` with the verification failure as its `reason`: `malformed_signature`, `invalid_signature`,
`missing_key`, or `timestamp_window`; a key or signature count over its limit raises it with the reason
`too_large`. Error strings and representations exclude delivery IDs, namespaces, operation references, entry IDs, and
causes; callers may read those attributes explicitly.

## Records, options, and exceptions

Generated packages also expose the shared contracts of the pagination, polling, stream, WebSocket, cache, upload, and
webhook helpers they declare, and copy only the runtime modules those helpers, the declared security schemes, request
bodies, and response headers, and the model backend need; `client.protocols` exists only with a helper, and `client.bodies`
only with a binary, multipart, or schema-less form body. Records, options, cache stores, and resume state come from
`client.protocols`. The client's `helper_defaults=` keyword is available only in packages that declare a pagination,
polling, stream, WebSocket, cache, or upload helper; see [client helper settings](#helper-settings-on-the-client). Helper
execution loads when `client.protocols`
is first used; ordinary operations share the same native HTTP client. Exceptions come from `client.errors`, each with the
helper that raises it. These imports need no HTTP library and start no threads. A client that uses no helper settings
loads none of these definitions: `client.errors` loads them the first time one of its names is used. Constructing a
record or option sends nothing.

### Selectors, targets, and origins

All records below are immutable and keyword-only. A field of the wrong type raises `TypeError`, including a
non-string where a string or one of several strings is expected; an invalid value raises `ValueError`. Values are
kept as given: a record never rewrites a name, pointer, or host into another spelling.

| Type | Fields and accepted values |
|---|---|
| `BodySelector` | `pointer: str`, an RFC 6901 pointer over wire names: `""` or a value starting with `/` in which `~` is followed only by `0` or `1` |
| `HeaderSelector` | `name: str`, an HTTP token; `occurrence: Literal['single', 'all'] = 'single'` |
| `StatusSelector` | No fields; selects the final status code |
| `ParameterTarget` | `location: Literal['path', 'query', 'header', 'cookie']`; `name: str`, nonempty, and an HTTP token for headers and cookies |
| `QuerystringTarget` | `name: str`, the nonempty declaration identity that is never sent; `pointer: str`, an RFC 6901 pointer where `""` is the whole value |
| `BodyTarget` | `pointer: str`, an RFC 6901 pointer where `""` is the whole body |
| `Origin` | `scheme: str`, `host: str`, and `port: int`, exactly as the client's URL rule gives them back for an absolute `http` or `https` URL |

`Selector` is `BodySelector | HeaderSelector | StatusSelector`, and `RequestTarget` is
`ParameterTarget | QuerystringTarget | BodyTarget`.

An `Origin` accepts exactly the triples that the client's own URL rule gives back unchanged: the rule spells the
origin as an absolute URL, interprets that URL, and the resulting scheme, host, and effective port must equal the
given ones. Anything the rule would rewrite or refuse raises `ValueError`, such as `Origin(scheme="https",
host="API.example.com", port=443)`, whose host the rule lowercases, or a scheme other than `http` or `https`. The
host is in the rule's own form; for example, an IPv6 address has no brackets, as in
`Origin(scheme="https", host="::1", port=443)`. A field of the wrong type, including a boolean port, raises
`TypeError`. Constructing an `Origin` loads the client's HTTP library to apply the rule.

### Poll snapshots and progress

`PollSnapshot[P]` is an immutable poll result with `state: JSONValue`, `terminal: bool`, `data: P`, and
`response: ResponseInfo`. The state is a copy of the given value, and the state and data are excluded from the
representation. `P` is covariant, so a `PollSnapshot[Pet]` is also a `PollSnapshot[object]`. `CancelReceipt[C]` is the
immutable response of a remote cancel request, with `data: C` and `response: ResponseInfo`; the data is excluded from
the representation, and `C` is covariant too.

`ProgressKey` is `Literal['pages', 'items', 'polls', 'reconnects', 'parts', 'confirmed_bytes', 'messages_sent',
'messages_received']`, and `ProtocolProgress` is `Mapping[ProgressKey, int]`.

Resume state encodes its value as canonical JSON: UTF-8 without whitespace, object members sorted by the code points
of their names, and strings escaped as Python's `json.dumps` escapes them with `ensure_ascii=False`, so only `"`, `\`,
and U+0000–U+001F are escaped. Numbers are written as `json.dumps` writes them: an integer in plain decimal and a
float as its shortest round-trip representation, so `1e16` stays `1e+16`. Decoding the result with `json.loads` and
encoding it again gives the same bytes. A value `json.dumps` cannot encode raises `TypeError`; a non-finite number, a
lone surrogate, a reference cycle, a value nested beyond the interpreter recursion limit, and an integer beyond the
interpreter's decimal conversion limit raise `ValueError`. A member name that is not a string is written as
`json.dumps` writes it.

### Upload records and sources

`UploadProgress(*, confirmed_bytes: int, total_bytes: int, complete: bool = False)` is how far an upload is; the
confirmed bytes never exceed the total. `UploadSource` is `bytes | bytearray | memoryview | BinaryIO`, the content an
upload reads; see [upload helpers](#upload-helpers). The handles are loaded only when first requested.

### Helper options

Every option field defaults to `UNSET`, imported from `client.options`. The effective defaults below apply after
merging. `None` removes a limit only where the table allows it. Counts and byte limits are integers, excluding
booleans. Durations are finite numbers of seconds, excluding booleans; integers are accepted. Invalid values raise
`ConfigurationError` with `reason='invalid_value'` and the field name as `field_path`.

| Type | Field | Effective default | Valid values |
|---|---|---|---|
| `PaginationOptions` | `max_pages` | `None` (no limit) | Positive integer or `None` |
| | `max_items` | `None` (no limit) | Nonnegative integer or `None`; `0` ends without sending |
| `PollOptions` | `max_polls` | `1000` | Positive integer or `None` |
| | `interval` | The declared interval, `1` second by default | Positive duration |
| | `max_wait` | `60` seconds | Positive duration or `None` |
| `StreamOptions` | `idle_timeout` | The native read timeout | Positive duration or `None` |
| | `reconnect` | `False` | `bool` |
| | `max_reconnects` | `5` | Nonnegative integer or `None` |
| | `max_reconnect_wait` | `60` seconds | Positive duration or `None` |
| `UploadOptions` | `chunk_bytes` | `8388608` | Positive integer |
| `CacheOptions` | `max_ttl` | `300` seconds | Positive duration: the cap on any entry's freshness |
| `WSOptions` | `open_timeout`, `idle_timeout`, `ping_interval`, `pong_timeout` | See [WebSocket limits](#websocket-limits) | Positive duration or `None` |
| | `max_message_bytes` | HTTPX2's default (64 KiB in 2.13) | Positive integer |
| Every type but `CacheOptions` | `total_timeout` | `600` seconds for polling, no limit otherwise | Nonnegative duration or `None`: the helper session's budget from its start |

### Protocol exceptions

Four classes cover what a helper reports beyond the core errors. Each derives from `SDKError`, comes from `client.errors`
only when the package declares a helper that raises it, and has a keyword-only constructor that does not validate field
values. Besides the fields below, each accepts `helper_id`, `operation`, `operation_id`, `info`, and `cause`.

| Exception | Fields |
|---|---|
| `ProtocolDataError` | `reason: str = 'value'`, `location: Selector \| RequestTarget \| None = None`, `data: object = None` |
| `SessionLimitError` | `reason: str`, one of `pages`, `items`, `polls`, `reconnects`, `parts`, `wait`, and `deadline`; `limit: float`, `progress: ProtocolProgress \| None = None`, kept as a read-only copy; `required_wait: float \| None = None` |
| `StreamInterruptedError` | `reason: str`, `eof` or `transport`; `sequence: int`, the last record delivered |
| `WebSocketClosedError` | `code: int \| None`, `reason: str` of at most 123 UTF-8 bytes, `clean: bool` |

`ProtocolDataError` has the `reason` `missing`, `null`, `type`, `value`, `malformed`, `inconsistent`, or `too_large` for
data that breaks the helper's rules, `pagination_cycle` for a continuation already seen, `operation_failed` or
`operation_cancelled` for a polled operation that reached that declared state, `error_event` for a declared error event
of a stream, and `malformed_signature`, `invalid_signature`, `missing_key`, or `timestamp_window` for a webhook that
failed verification. `data` is the value the server sent with it, decoded as declared: the final poll's data or the
error event's. `SessionLimitError` names the cap in `reason`; `wait` and `deadline` mean that a server's delay, kept in
`required_wait`, is longer than the allowed wait or the remaining deadline. `progress` is copied into a read-only
mapping, and the handle's `checkpoint()` continues the operation.

Other refusals use the core errors. A call or checkpoint a helper refuses, such as a step while another runs, a step
after a failure or `close()`, an expired or non-resumable checkpoint, a source whose size changed, or a validator header
that conflicts with the cache entry, is a `ConfigurationError` with a `field_path` and a `reason` such as
`invalid_state`, `expired`, `wrong_capability`, `source_changed`, or `binding_mismatch`. A failed WebSocket handshake
negotiation, and a send or upload request that may have reached the server, is an `APIConnectionError` with the reason
`negotiation_failed` or `delivery_unknown`. A stream event, NDJSON record, or WebSocket message that does not decode is
a `DecodeError` with its `location`. A cache store that fails is an `SDKError` with the reason `store_failed` and the
store's exception as `cause`.

Messages and representations exclude locations, progress, resume state, raw bytes, event data, and tags; read those
attributes explicitly.

---

# Python Client Reference

Source: https://datamodel-code-generator.koxudaxi.dev/python-client-reference/

!!! warning "Experimental"

    HTTPX2 client generation is experimental. Its options, generated package, and template values may change. See
    [Experimental Features](experimental.md).

This page is the reference behind [Python Client Generation](python-client.md): how the generated methods are
declared, how values are converted, and the full rules of timeouts, retries, request bodies, redirects, templates,
and errors. The guide covers the common cases with tested examples; come here for the precise rules of one setting.
The [protocol helpers](python-client-helpers.md) have a page of their own. The examples use the layout of the guide's
quick start: the generated package `app.client` and its models `app.models`, inside the application package `app`. The
text calls the generated package `client`, as in `client.errors`.

## Signature style

[`--client-signature-style`](cli-reference/target-generation-options.md#client-signature-style) chooses how every
operation method of the generated package declares its keyword arguments.

| Option | Values | Default | Where |
|---|---|---|---|
| `--client-signature-style` | `"explicit"`, `"unpack"` | `"explicit"` | `--client-signature-style unpack`; `pyproject.toml`: `client-signature-style = "unpack"`; `generate()`: `client_signature_style="unpack"` |

It is one choice for the whole package: there is no per-operation setting and no call-time switch. It changes only
how methods are declared. The calls a method accepts, the requests it sends, its results, and its errors are the same
in both styles, and the model backend is unaffected: `unpack` does not turn your models into TypedDicts.

### `explicit`

Every keyword is a real keyword-only parameter of the method and of each of its overloads:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.signature-style.explicit -->
<!-- fmt: off -->

```python
    @overload
    def get_pet(
        self,
        *,
        petId: int,
        response_media_type: None = None,
        options: RequestOptions | None = None,
    ) -> models.Pet: ...
    @overload
    def get_pet(
        self,
        *,
        petId: int,
        response_media_type: Literal['application/json'],
        options: RequestOptions | None = None,
    ) -> models.Pet: ...
    @overload
    def get_pet(
        self,
        *,
        petId: int,
        response_media_type: Literal['text/plain'],
        options: RequestOptions | None = None,
    ) -> models.PetsPetIdGetResponse: ...
    def get_pet(
        self,
        *,
        petId: int,
        response_media_type: Literal['application/json', 'text/plain'] | None = None,
        options: RequestOptions | None = None,
    ) -> GetPetResponse:
        """
        Call GET /pets/{petId}.
        """
        return self._core.execute(
            _operations.OPERATION_2,
            (petId,),
            options=options,
            response_media_type=response_media_type,
        ).data
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.signature-style.explicit -->

### `unpack`

Every overload and the implementation take `**kwargs` typed by a TypedDict of that signature's keywords:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.signature-style.unpack -->
<!-- fmt: off -->

```python
    @overload
    def get_pet(
        self,
        **kwargs: Unpack[Operation2Arguments],
    ) -> models.Pet: ...
    @overload
    def get_pet(
        self,
        **kwargs: Unpack[Operation2Arguments1],
    ) -> models.Pet: ...
    @overload
    def get_pet(
        self,
        **kwargs: Unpack[Operation2Arguments2],
    ) -> models.PetsPetIdGetResponse: ...
    def get_pet(
        self,
        **kwargs: Unpack[Operation2Arguments3],
    ) -> GetPetResponse:
        """
        Call GET /pets/{petId}.
        """
        KEYWORDS_2.check(kwargs)
        return self._core.execute(
            _operations.OPERATION_2,
            (kwargs['petId'],),
            options=kwargs.get('options'),
            response_media_type=kwargs.get('response_media_type'),
        ).data
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.signature-style.unpack -->

The TypedDicts live in the private module `client._generated.client_arguments`, one for each distinct signature of an
operation, shared by its normal, `with_response`, `with_raw_response`, and `with_streaming_response` views. Their
names follow the operation's position and may change between generations, so do not import them: declare your own
TypedDict with the keys you forward. The module also holds the list of keywords each method takes:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.signature-style.records -->
<!-- fmt: off -->

```python
class Operation2Arguments(TypedDict):
    """The keyword arguments of one signature of get_pet."""

    petId: int
    response_media_type: NotRequired[None]
    options: NotRequired[RequestOptions | None]


class Operation2Arguments1(TypedDict):
    """The keyword arguments of one signature of get_pet."""

    petId: int
    response_media_type: Literal['application/json']
    options: NotRequired[RequestOptions | None]


class Operation2Arguments2(TypedDict):
    """The keyword arguments of one signature of get_pet."""

    petId: int
    response_media_type: Literal['text/plain']
    options: NotRequired[RequestOptions | None]


class Operation2Arguments3(TypedDict):
    """The keyword arguments of one signature of get_pet."""

    petId: int
    response_media_type: NotRequired[Literal['application/json', 'text/plain'] | None]
    options: NotRequired[RequestOptions | None]


KEYWORDS_2: Final = Keywords(
    'get_pet',
    ('petId', 'response_media_type', 'options'),
    ('petId',),
)
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.signature-style.records -->

### What differs between the styles

Both styles accept the same direct calls, and forwarding a mapping whose type declares known keys:

```python
from typing_extensions import NotRequired, TypedDict

from app.client import Client
from app.client.options import RequestOptions


class GetArguments(TypedDict):
    petId: int
    options: NotRequired[RequestOptions | None]


def forward(client: Client, arguments: GetArguments) -> None:
    print(client.pets.get_pet(**arguments))
```

- **Introspection.** `inspect.signature` shows the keyword-only parameters of an `explicit` method, and a single
  `**kwargs` parameter for an `unpack` method. `typing.get_type_hints(method, include_extras=True)` resolves the
  TypedDict of an `unpack` method from any module, whose keys are the same keywords, optional ones marked
  `NotRequired`.
- **Binding errors.** An unknown keyword or a missing required one raises `TypeError` in both styles, before anything
  is sent. Python binds an `explicit` async method when it is called, while an `unpack` async method checks its
  keywords when it is awaited; async streaming methods, which are ordinary functions, check them when called. The
  wording of the error message is not the same.
- **Type checkers.** Both styles give the same keywords the same types. Checkers treat a TypedDict with extra keys
  differently: forwarding one to an `explicit` method is an error for mypy, Pyright, and ty, while for an `unpack`
  method only mypy reports it. The method still refuses the extra key at runtime.

## Body field arguments

[`--client-body-arguments`](cli-reference/target-generation-options.md#client-body-arguments) chooses whether a call
may give the declared fields of an object body as keyword arguments instead of the body. `"body"`, the default, keeps the body argument alone; `"both"` adds the fields of every body that can
take them next to the body argument, on every view of the method.

| Option | Values | Default | Where |
|---|---|---|---|
| `--client-body-arguments` | `"body"`, `"both"` | `"body"` | `--client-body-arguments both`; `pyproject.toml`: `client-body-arguments = "both"`; `generate()`: `client_body_arguments="both"`; one operation: its `body_arguments` member of `--client-operations`, where `null` inherits the package's |
| `body_field_names` of `--client-operations` | Property names by media type | none | One operation: its `body_field_names` member of `--client-operations`, such as `{"application/json": {"tag": "pet_tag"}}` |

With `"both"`, a JSON body whose model is `NewPet` takes either call:

```python
from app.client import Client
from app.models import NewPet

with Client() as client:
    client.pets.create_pet(body=NewPet(name="Mimi", tag="cat"), media_type="application/json")
    client.pets.create_pet(name="Mimi", tag="cat", media_type="application/json")
```

In `pyproject.toml`, the same settings are:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.body-fields.pyproject -->
<!-- fmt: off -->

```toml
[tool.datamodel-codegen]
input = "fields.yaml"
input-file-type = "openapi"
output = "app/models.py"
output-model-type = "pydantic_v2.BaseModel"
openapi-scopes = ["schemas", "api"]
target-python-version = "3.11"
formatters = ["builtin"]
disable-timestamp = true
openapi-include-paths = ["/pets*", "/owners"]
generate-client = "httpx2"
client-output = "app/client"
client-package = "app.client"
client-model-package = "app.models"
client-body-arguments = "both"

[tool.datamodel-codegen.client-operations."/paths/~1pets/post".body_field_names]
"application/json" = { tag = "pet_tag" }
"application/x-www-form-urlencoded" = { tag = "pet_tag" }

[tool.datamodel-codegen.client-operations."/paths/~1pets~1{petId}~1visits/post"]
body_field_names = { "application/json" = { options = "visit_options" } }

[tool.datamodel-codegen.client-operations."/paths/~1pets~1{petId}~1owner/put"]
body_arguments = "body"
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.body-fields.pyproject -->

### Which bodies take fields

A JSON or form body takes fields when its schema is one object whose model its backend constructs from them, an
object that may be null included: Pydantic models and dataclasses, stdlib dataclasses, TypedDicts, and msgspec
Structs alike. Other bodies keep only `body`: unions of objects, arrays and scalars, bodies without a schema, binary
bodies and form-data sent as parts, bodies whose model cannot hold a request, such as one with a required read-only
member. Extra keys, a null body, and an empty object also need `body`, and a nested object is given as its own model.

Each field argument takes its model field's name, as the model naming options give it, or for a key that is no
identifier the name such a field would take, and a read-only member has none. A field whose name a parameter, a
call option such as `body` or `options`, or another field takes is suffixed, such as `name_1`.
`body_field_names` names one field of one media type instead, without changing the model or the wire property. Fields
of different media types may share a name. Generation fails when a body field name or an `--aliases` entry takes the
name of a parameter, a call option, or another field of the same media type, and when a body field name names no
field argument or its operation keeps only `body`:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.body-fields.diagnostics -->
<!-- fmt: off -->

```text
--client-operations: The body field name of the application/json property 'id' of POST /pets names no field argument
--client-operations: The body field name of the application/xml property 'tag' of POST /pets names no field argument
--client-operations: The body field name of the application/json property 'absent' of POST /pets names no field argument
/paths/~1pets/post: The application/json body fields of POST /pets cannot take the argument names 'media_type', 'tag', which other arguments take
--client-operations: The body field name of the text/plain property 'q' of POST /search names no field argument
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.body-fields.diagnostics -->

### Signatures

The body and each media type's fields are separate overloads. The body's takes every field as `UNSET`; a field
overload takes the body as `UNSET`, the fields its model's constructor requires without a default, and its other
fields with `UNSET`, and a field takes `None` only when its property is nullable. A field is required exactly when the
generated model requires it, so `--force-optional` and defaults make it optional. An optional body whose fields are all optional has one
overload for each field, which that overload requires, and one that takes nothing and sends nothing:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.body-fields.overloads -->
<!-- fmt: off -->

```python
    @overload
    def update_pet(
        self,
        *,
        petId: int,
        body: models.PetPatch,
        name: UNSET = UNSET,
        tag: UNSET = UNSET,
        media_type: Literal['application/json'] | None = None,
        options: RequestOptions | None = None,
    ) -> UpdatePetResponse: ...
    @overload
    def update_pet(
        self,
        *,
        petId: int,
        body: UNSET = UNSET,
        name: str,
        tag: str | None | UNSET = UNSET,
        media_type: Literal['application/json'] | None = None,
        options: RequestOptions | None = None,
    ) -> UpdatePetResponse: ...
    @overload
    def update_pet(
        self,
        *,
        petId: int,
        body: UNSET = UNSET,
        name: str | UNSET = UNSET,
        tag: str | None,
        media_type: Literal['application/json'] | None = None,
        options: RequestOptions | None = None,
    ) -> UpdatePetResponse: ...
    @overload
    def update_pet(
        self,
        *,
        petId: int,
        body: UNSET = UNSET,
        name: UNSET = UNSET,
        tag: UNSET = UNSET,
        media_type: None = None,
        options: RequestOptions | None = None,
    ) -> UpdatePetResponse: ...
    def update_pet(
        self,
        *,
        petId: int,
        body: models.PetPatch | UNSET = UNSET,
        name: str | UNSET = UNSET,
        tag: str | None | UNSET = UNSET,
        media_type: Literal['application/json'] | None = None,
        options: RequestOptions | None = None,
    ) -> UpdatePetResponse:
        """
        Call PATCH /pets/{petId}.
        """
        return self._core.execute(
            _operations.OPERATION_1,
            (petId,),
            body=body,
            fields=(name, tag),
            media_type=media_type,
            options=options,
        ).data
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.body-fields.overloads -->

The implementation takes every field with an `UNSET` default, and with `signature_style = "unpack"` each overload
takes its own TypedDict.

### Calls

A call gives the body or the fields of the media type it sends, never both, and an explicit `UNSET` counts as
omitted. The method refuses any other binding before any request or stream: with `TypeError` for a body with
fields, a missing required field, a field of another media type, or fields for a media type that takes none, and with
`ConfigurationError` for a missing or undeclared media type, as it does for bodies.

- Only the fields a call gives are sent: the model's defaults are not, and `None` sends `null`.
- A required body whose fields are all optional is sent as `{}` when a call gives none of them. An optional body is
  omitted, and naming only its media type still raises `ConfigurationError`.
- The model is built from the fields by its constructor, which validates Pydantic models and dataclasses, while stdlib
  dataclasses, TypedDicts, and msgspec Structs take the values as given.

## Model codecs

The generated models determine validation and conversion. Text in parameters, response headers, forms and text parts
is decoded before the selected backend handles it: a declared integer, number or boolean becomes that builtin when the
text is its canonical JSON literal. Pydantic and msgspec receive any other text unchanged and decide by their native
conversion rules, as they do for unknown object members. Dataclass and TypedDict codecs validate nothing, so for them
such text is a decoding error, like text that cannot become a `Decimal`, date or `UUID` leaf; their JSON bodies are
still constructed without added schema validation. Repeated undeclared members keep their last value.

A package holds the codec of its own model backend only. A Pydantic package imports no msgspec, a msgspec package no
Pydantic, and a dataclass or TypedDict package neither, so the package imports, and mypy, Pyright, and ty check it,
with only the dependencies that generation prints installed.

Generated clients send and read model values through their model backend, with no validation layer of their own:

| Backend | Sends | Receives |
|---|---|---|
| Pydantic v2 `BaseModel` | `model_dump_json(by_alias=True, exclude_unset=True)`; other types through a cached `TypeAdapter` | `TypeAdapter(T).validate_json` |
| Pydantic v2 dataclass | `TypeAdapter(T).dump_json(by_alias=True)`, which leaves out the fields that hold `MISSING` | `TypeAdapter(T).validate_json` |
| `msgspec.Struct` | `msgspec.json.encode` | `msgspec.json.Decoder(T).decode` |
| dataclasses, `TypedDict` | `json.dumps` of the renamed fields | `json.loads`, then the renamed fields |

Adapters and decoders are built on a type's first use and cached for the process. dataclasses and `TypedDict` have no
validation of their own: the generated converter renames wire names to fields and builds nested models, lists, sets,
tuples, dicts, and optionals, and converts only `datetime`, `date`, and `time` (with `fromisoformat`), `UUID`,
`Decimal` (sent as a string), an `Enum` by value (an unknown value fails), and `bytes` as base64. A `TypedDict` keeps
unknown keys and leaves out absent ones; a dataclass drops unknown keys and leaves out a field whose value is its
`None` default.

- **Requests.** Arguments and bodies are serialized from the model values as given. Aliases, presence, and the
  conversion of dates, decimals, enums, and media follow the models. A value is checked only as far as its model's
  constructor already checked it, and what the serializer cannot represent fails with a request `DecodeError` with the
  reason `unencodable` before anything is sent; its `location` names the argument, never the value. An empty array or
  object in a style-encoded parameter or a form member is left out as an omitted value is: it writes no query pair,
  header, cookie, or part. A style or a form cannot write null, so a `None` member of an object parameter or of a
  URL-encoded or multipart form, and a `FieldPart` whose value is `None`, are left out the same way. A multipart form
  that is left with no part is still sent, as its closing boundary alone. A path segment cannot be left out, so an
  empty array or object in a path parameter fails with a request `DecodeError` before anything is sent.
- **Parameter arguments.** A parameter whose model type is a type alias or a root model takes the type it stands for,
  such as `limit: int` or `tags: list[str]`, never the alias or the root model. An alias's argument is sent as given,
  without validation. With Pydantic models, an argument whose parameter is a root model is built into it before it is
  sent, which checks it as the root model's constructor does: a value it refuses fails with a request `DecodeError`
  with the reason `unencodable`.
- **Parameter defaults.** An optional parameter whose schema declares a boolean, number, or string default of its
  builtin type, alone or with null, defaults to it, such as `limit: int = 20`; any other optional parameter defaults to
  `UNSET`. A parameter with such a default is always sent, with the default when the call omits it: the client pins
  the default it was generated with, so a later change of the server's default does not apply until you regenerate,
  and a default that breaks its own schema's constraints is sent as it is. A path parameter that names a placeholder
  of its path is a required argument without a default, as OpenAPI requires, even when the document leaves out
  `required` or declares it `false`; a document with a path parameter that names no placeholder of its path is refused.
- **Responses.** Bodies, parts, stream events, and socket messages are converted by the model backend into the declared
  types, which check what those types declare and coerce as the backend does; a value the type refuses raises
  `DecodeError` with the reason `invalid_value`. Read-only and write-only behavior follows the generated model options.
- **Binding.** A missing required argument, an unknown keyword, or a media type the operation does not declare fails
  before anything is sent. A parameter value with text that UTF-8 cannot encode, such as a lone surrogate, fails with
  a request `DecodeError` of the reason `unencodable`, with a `ParameterEncodingError` cause, before anything is sent.
- **Path segments.** Path arguments that make their segment `.` or `..` once encoded in their parameters' styles and
  put into the path template, `%2E` in either case counting as `.`, such as `..` in the simple style, the empty string
  in the label style, or `%2e` with `allowReserved`, fail with a request `DecodeError` at the segment's first parameter
  whose encoded text is non-empty, with a `ParameterEncodingError` cause, before anything is sent: URL normalization in
  clients, proxies, and servers would remove the segment and send the call to another resource, and encoding the dots
  does not prevent it. `...` and `.a` are sent as they are, and a dot segment the path template spells is not refused.
- **Path text.** The literal text of a path template is sent as RFC 3986 allows it in a path, as path arguments are:
  any other character, such as `\`, `|`, `^`, `[`, `]`, `?`, `#`, a space, or non-ASCII text, is percent-encoded as
  UTF-8, `\` as `%5C`, so no client, proxy, or server reads `\` as `/` or ends the path early. A `%` and two hex
  digits is an octet the document already encodes and is sent as it is, so `/files/a%20b` sends `a%20b`, which the
  generated server routes by its decoded value; any other `%` is sent as `%25`. The client holds the encoded path from generation, so calls pay nothing for it.
- **Header names.** A header parameter, response header, or part header whose name is not an RFC 9110 token, such as
  `X Sp` or `X-Näme`, stops generation with an error, as it stops the generated server's, since no HTTP client or
  server can send it. A declared media type whose text is not ASCII header text, such as `text/plain; label="café"`,
  stops generation too, since its Content-Type could not be sent; a call's `media_type` of such text raises
  `ConfigurationError` with the reason `invalid_value` and the `field_path` `("headers", "Content-Type")`.
- **Header values.** A header carries header text only: HTAB, SP, and visible ASCII, without whitespace at either end,
  the text every HTTP client and server reads alike. RFC 9110 leaves any other byte opaque, and servers read it as
  Latin-1 or as UTF-8; the generated FastAPI server answers `400` for it in a header parameter of the operation. A
  header parameter of any style, or of text content, whose value, array item, or object member is any other text, such
  as `café` or one with a control character, fails with a request `DecodeError` of the reason `unencodable`, with a
  `ParameterEncodingError` cause, before anything is sent, instead of arriving as other text. A header parameter of JSON
  content is written with its non-ASCII text and DEL escaped, so it carries any text; declare the header that way, or
  apply an encoding the API defines yourself, such as percent-encoding, Base64, or RFC 8187, and decode it in the
  service. The headers of `default_headers` and `extra_headers` and an `idempotency_key` follow the same rule; see
  [timeouts and cancellation](#timeouts-and-cancellation). A value a server gave that a protocol helper writes to a
  header parameter, such as an event ID, a cursor, or a binding's value, follows it too. A declared response header is
  read by the same rule: a value with a byte outside ASCII fails its `decode_..._header` accessor with a response
  `DecodeError` of the reason `invalid_header`, with a `MalformedError` cause, so its text does not depend on how HTTPX2
  decodes the response's headers, as a whole set: ASCII, else UTF-8 when every header of the response is UTF-8, else
  Latin-1. `ResponseInfo.headers` keeps the text HTTPX2 decodes. The generated server sends ASCII header text only.
- **Cookies.** A cookie parameter with a single value is sent as it is, without percent-encoding, which is how HTTP
  clients send cookies and how the generated server reads them. A cookie cannot carry `;`, `,`, `"`, `\`,
  whitespace, control characters, or non-ASCII text (RFC 6265), so such a value fails with a request `DecodeError`
  of the reason `unencodable`, with a `ParameterEncodingError` cause, before anything is sent, instead of arriving
  cut short. Encode a value that needs those characters yourself, for example as Base64, and decode it in the
  service. Such a parameter whose name is not a token stops generation with an error. Array and object cookie
  parameters send one cookie for each item or property, percent-encoded in the `form` style.
- **Headers.** Header values are converted through their native types. Read a body without any model with
  `with_raw_response` or `with_streaming_response` instead.

A union of object models read by a stdlib dataclass or TypedDict converter needs a declared discriminator. Without
one, generation raises `Error` naming the use:

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: python-client.model-codecs.diagnostics -->
<!-- fmt: off -->

```text
/paths/~1animals~1any/put/requestBody: The union of Cat and Dog needs a declared discriminator for the dataclasses.dataclass converter
/paths/~1kin/put/requestBody: The union of Animal and Cat needs a declared discriminator for the dataclasses.dataclass converter
```

<!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: python-client.model-codecs.diagnostics -->

## Timeouts and cancellation

The guide's [timeouts](python-client.md#timeouts) cover the settings; the details below cover the budget across
attempts, cancellation, streams, and the clock the client reads.

### An optional budget across attempts

The runtime supplies no whole-call budget by default. Set `Client(total_timeout=60)` to bound every call to a minute.
Native phase timeouts bound each I/O wait; they do not limit the total duration of a call that keeps making progress.

```python
import httpx2

from app.client import Client
from app.client.options import RequestOptions


def read_with_budget(client: Client, url: str) -> bytes:
    options = RequestOptions(total_timeout=10, timeout=httpx2.Timeout(3, connect=2))
    return client.request_raw("GET", url, options=options).read()
```

The budget is checked before each attempt and retry wait and caps each native I/O timeout. A native timeout raises
`APITimeoutError` with the reason `phase_timeout`, or `deadline_exceeded` once the budget has expired, with the native
failure as `cause`. A fully received response stays available when decoding or cleanup finishes after expiry.

### Native cancellation

Async calls run in their caller's task. Cancel that task through the native backend; its cancellation exception
propagates unchanged. The SDK never uncancels the task, selects a competing outcome, or wraps a `BaseException`.
Responses and bodies are released in `finally`, and callbacks such as the HTTP client's `event_hooks` run in the
caller's cancellation scope. Synchronous preparation and callbacks remain cooperative.

### Streaming after handoff

Streaming uses the native read timeout for idle I/O. An optional acquisition budget caps the request's native
phase timeouts before sending; it does not add a separate stream lifetime timer.

```python
from typing import BinaryIO

import httpx2

from app.client import Client
from app.client.options import RequestOptions


def download(client: Client, url: str, destination: BinaryIO) -> None:
    options = RequestOptions(timeout=httpx2.Timeout(600, read=60))
    with client.with_streaming_response.request_raw("GET", url, options=options) as response:
        response.stream_to(destination)
```

Always leave the response's context manager, including when abandoning a download early. A configured helper
session may additionally stop before its next step when its total budget has expired.

`stream_to(path)` writes the decoded body to a temporary file beside the target and moves it there once the body is
complete; an existing target raises `FileExistsError` unless `overwrite=True`, and a consumed handle raises
`ConfigurationError` with the reason `response_consumed`. A failure removes the temporary file and leaves the target
unchanged. In async calls the file calls run one at a time in a worker thread, and a cancellation during the final move
lets the move finish. `stream_to(file_object)` writes to a borrowed file and never closes, seeks, or truncates it.

### Clocks and retry jitter

`Client(clock=Clock(...))` replaces the time, jitter, and wait sources of every call a client makes. Views and requests
cannot change it. Each source is a function:

| Source | Default | Read for |
|---|---|---|
| `monotonic` | `time.monotonic` | Deadlines, elapsed times, retry targets, token expiry, and protocol helper sessions, poll intervals, and stream deadlines |
| `time` | `time.time` | Placing a wall-clock instant on the monotonic scale once: an HTTP-date `Retry-After` or polling delay header at receipt and an access token's `expires_at`; a polling, stream, or upload helper's `resume` check of its state's `expires_at`; and a cache fetch's request, response, and age times |
| `random` | A secure uniform draw | The fraction in `[0, 1)` of a full-jitter backoff, drawn only when a retry needs one |
| `sleep` | `time.sleep` | Each wait of a synchronous client, given its seconds: retry waits, polling intervals, and stream reconnection waits |
| `asleep` | `anyio.sleep` | Each wait of an asyncio client, given its seconds, returning the awaitable the call waits on, which task cancellation interrupts |

A source that cannot be called raises `ConfigurationError` with the `field_path` `("clock", name)`. OAuth providers
keep their own time through their `clock=` argument and must agree with their clients on wall time. Retry,
polling, and reconnection waits pass the remaining duration to the clock's `sleep` or `asleep`, and I/O timeouts
use the duration the monotonic source measured. A test that records the waits and advances its own monotonic
source by each one runs every wait at once and can check its length:

```python
from app.client import Client
from app.client.options import Clock


class FakeTime:
    def __init__(self) -> None:
        self.now = 0.0
        self.waits: list[float] = []

    def monotonic(self) -> float:
        return self.now

    def sleep(self, seconds: float) -> None:
        self.waits.append(seconds)
        self.now += seconds


def instant_retries(url: str, fake: FakeTime) -> Client:
    return Client(base_url=url, clock=Clock(monotonic=fake.monotonic, sleep=fake.sleep))
```

Each retry of this client starts at once, server delays included, and `fake.waits` holds the waits it chose.

## Instrumentation

The SDK adds no hook or limiter layer of its own. Instrument calls on the HTTP client: pass an `httpx2.Client` or
`httpx2.AsyncClient` with `event_hooks`, or a wrapping transport, as `http_client`. Request hooks see every attempt and
followed redirect, credentials included, and response hooks every response. An ordinary exception a hook raises ends
the call as `APIConnectionError` with that exception as `cause`, and the call is not sent again. Limit concurrency
with the HTTP client's pool limits or an application semaphore.

```python
import httpx2

from app.client import Client


def log_request(request: httpx2.Request) -> None:
    print(request.method, request.url.path)


def log_response(response: httpx2.Response) -> None:
    print(response.status_code, response.request.url.path)


def instrumented(url: str, http: httpx2.Client) -> Client:
    http.event_hooks = {"request": [log_request], "response": [log_response]}
    return Client(http_client=http, base_url=url)
```

An injected client stays the caller's: close it after the SDK client.

### Counters and cleanup

`ResponseInfo` and every `SDKError` expose `attempt_count`, counted at send time, `elapsed`, and `request_id`, also
when no response arrived. Closing a root refuses new calls from the root and its views and closes its created native
client once; borrowed clients and providers keep the caller's lifetime. Responses and files opened from paths are
released in `finally`; a release failure is named in the notes of the primary error, or propagates without one.

## Retries and operation contracts

`max_retries` and `retry=RetryOptions(...)` apply on clients, views, and calls. The fields of `RetryOptions` merge
independently; omitted fields inherit, while a status set replaces the inherited set, and `retry=None` inherits the
whole record. Automatic retries require a candidate failure or status, operation safety, replayable input, and enough
time. JSON/model decoding, arbitrary callbacks,
cancellation, and logical deadlines never restart a request.

| Setting | Effective default | Meaning |
|---|---|---|
| `max_retries` | `2` | Retries after the initial attempt; `0` disables retries; a setting of its own, not a `RetryOptions` field |
| `initial_delay`, `max_delay` | `0.5`, `8` seconds | Exponential backoff, with maximum at least the initial delay |
| `jitter` | `"full"` | Uniform delay below the exponential cap; `"none"` uses the cap |
| `statuses` | `{408, 429, 500, 502, 503, 504}` | Replace with an integer set in 400–599; 401/403/407 are forbidden |
| `max_retry_after` | `60` seconds | Positive cap on accepted server delay; `None` removes this cap |
| `respect_retry_after` | `True` | Explicit `False` ignores server delay hints |
| `retry_after_ms_header`, `should_retry_header` | Operation declaration, otherwise `None` | Vendor controls require generated metadata; explicit `None` disables one |
| `retry_on_pool_timeout` | `False` | Avoid amplifying pool contention unless explicitly enabled |

GET, HEAD, OPTIONS, PUT, and DELETE are eligible for retries by default. POST, PATCH, and other methods require an explicit
`retry_safety="idempotent"` declaration or a valid server key contract. A native `ConnectError` (TLS and DNS failures
included), `ConnectTimeout`, or `PoolTimeout` proves the request unsent and can permit otherwise unsafe methods,
unless an earlier attempt of the call, or a response HTTPX2 followed a redirect from, reached the server; every other
failure after the send started may have been sent and is never sent again. `retry_safety="never"` prohibits every
resend, including an unsent request.

A server delay is a minimum: the client never shortens it to fit `max_retry_after` or the remaining deadline, and a
valid server veto prevents a retry. `Retry-After` gives seconds or an HTTP date, read by the standard library's
`email.utils.parsedate_to_datetime`: a date without a zone, with `-0000`, or with an unknown zone is UTC, and an
impossible date, such as one with a leap second, is ignored. The two-digit year of an RFC 850 date is the latest that
is at most 50 years after receipt, as RFC 9110 reads it; a year below 100 in another form is read as 1969 to 2068.
Without a valid hint, bounded exponential backoff applies. Retry waits consume the same logical budget as sending and
decoding. `RetryOptions(respect_retry_after=False)` is an explicit application policy override, disclosed in every
generated README, `app/client/README.md`; it is never silently embedded in generated defaults.

```python
from app.client import Client
from app.client.options import RequestOptions, RetryOptions


def fetch_with_retries(client: Client, url: str) -> bytes:
    options = RequestOptions(
        max_retries=2,
        retry=RetryOptions(max_retry_after=20),
        follow_redirects=True,
        total_timeout=30,
    )
    return client.request_raw("GET", url, options=options).read()
```

Buffered and streaming raw APIs return the final HTTP response when status retries end, including non-2xx statuses.
Transport, policy, deadline, and cancellation failures still raise. A response release failure
stops a planned retry after its response was discarded: the call then raises that response's `APIStatusError` with the
failure named in its notes.
Typed operations retain final response metadata in their `APIStatusError`. A streaming response can retry during
acquisition; after handoff, body failures terminate that stream and never issue another request.

### Declare API guarantees during generation

Operation guarantees are set per operation in `--client-operations`, or `client-operations` of `pyproject.toml`.
This example assumes `api.yaml` declares `POST /orders`:

```toml
[tool.datamodel-codegen.client-operations."/paths/~1orders/post".runtime]
retry_safety = "method_default"
retry_after_ms_header = "X-Retry-In-Ms"
should_retry_header = "X-Retry-Permitted"
idempotency = { header_name = "Idempotency-Key" }
```

With the [Python API](python-client.md#python-api), the same operation setting is a mapping of `client_operations`:

```python
client_operations = {
    "/paths/~1orders/post": {
        "runtime": {
            "retry_safety": "method_default",
            "retry_after_ms_header": "X-Retry-In-Ms",
            "should_retry_header": "X-Retry-Permitted",
            "idempotency": {"header_name": "Idempotency-Key"},
        },
    },
}
```

Only `header_name` is required for idempotency. The key header must be an HTTP token and cannot share
an outgoing position with an effective parameter or authentication header. The two response control headers must
have distinct names. Header comparisons ignore ASCII case; outgoing and incoming positions are independent.
Unknown keys, malformed values, and ownership conflicts fail generation with an error naming the
setting. The generated README lists only the finalized selected operations and their contracts.

### Supply and retain an idempotency key

The `idempotency` setting's `header_name` declares the API's idempotency key header. A key belongs to one call:
supply the caller's own as `RequestOptions(idempotency_key="saved-value")`.

Unset, the client creates one UUID4 key per logical call for an operation with a declared header.
`idempotency_key=None` disables that automatic key. A caller key on an undeclared operation or `request_raw` fails
before sending with `ConfigurationError` and the reason `not_declared`. A header of the declared name among the call's
`extra_headers` or the client's or a view's `default_headers` is sent as it is and is the call's key instead, the same
on every call it reaches; a protocol helper, which needs a key per request, refuses it. The same key is sent unchanged on every eligible
retry. A declaration without an active key does not authorize unsafe retries. The contract does not guarantee
exactly-once business execution. A key is [header text](#model-codecs), HTAB, SP, and visible ASCII without
whitespace at either end: for any other value, such as `clé`, a line break, a space at its end, or a number,
`RequestOptions(idempotency_key=...)` raises `ConfigurationError` with the reason `invalid_value` and the
`field_path` `("idempotency_key",)`.

```python
from app.client import Client
from app.client.options import RequestOptions


def keyed_options(value: str) -> RequestOptions:
    return RequestOptions(idempotency_key=value)
```

Pass the returned options to an operation with the matching declaration. The client reuses the supplied value across
eligible retries.

## Request compression

### Declare accepted codings

The `accepted_content_encodings` runtime setting, empty by default, lists the request content codings an operation
accepts. Values are HTTP tokens compared in lowercase, without duplicates; `gzip` is the only coding with a
builtin encoder, so another value, including `identity`, fails generation, and so does a repeated
one. As in [Declare API guarantees during generation](#declare-api-guarantees-during-generation):

```toml
[tool.datamodel-codegen.client-operations]
"/paths/~1items/post" = { runtime = { accepted_content_encodings = ["gzip"] } }
```

The generated README lists the operations that accept a coding.

### Select a coding

`Client(compression="gzip")` is the default. The SDK gzips only bodies of operations that declare gzip;
`Client(compression=None)` disables it. Views and calls inherit the client setting; a package without such an
operation has no `compression` setting. Undeclared operations,
bodyless requests, raw requests, and token requests stay uncompressed. A Content-Encoding header conflicts only
when the SDK compresses the body. The gzip encoder uses level 6 and a zero modification time.

Bytes and encoded bodies are compressed once and every retry resends the same bytes. Files, paths, iterables, and
multipart bodies are compressed as each attempt streams, without a Content-Length, and replay exactly as they would
uncompressed; a one-shot body stays one-shot.

Each protocol helper request follows its own operation's declaration and the client setting. Bodyless polls and
followed URLs stay uncompressed. Token requests are never compressed.

## Body replay and resource ownership

A package accepts the request bodies its operations declare. A schema-less form body exposes `FormData` in `bodies.py`
and uses the core operation runtime, without the binary or multipart body runtime. Without a binary or multipart
request body, `request_raw` takes `bytes`; with a binary body `request_raw` also takes the binary inputs below, and
with a `multipart/form-data` body a `MultipartBody` (`AsyncMultipartBody` for an asyncio client) as well. Encoded
bytes, JSON included, are kept once per logical call and resent unchanged; a multipart body keeps its boundary.

A binary body, and the content of a multipart `FilePart`, is one of these inputs. Nothing is buffered or spooled to
make a one-shot input replayable.

| Input | Calls | How it is read | Framing | Sent again |
| --- | --- | --- | --- | --- |
| `bytes` | sync, async | Sent as given. | `Content-Length` | Yes |
| Binary file object with a synchronous `read` | sync, async | `read` in chunks of at most 64 KiB from its position at call entry, up to the length measured there when it can seek, else until it returns no bytes. | `Content-Length` when it can `tell` and `seek`, else chunked | Yes after seeking back; no when it cannot seek |
| `os.PathLike` path such as `Path` | sync, async | Opened in binary mode when the body is first sent, read like a file, closed when the call ends. | `Content-Length`; chunked when its file cannot seek, such as a FIFO | Yes; no when its file cannot seek |
| Iterable of `bytes` | sync, async | Iterated once; each item is sent as it is yielded. | Chunked | No |
| Async file object whose `read` is a coroutine function, such as an `anyio` or `aiofiles` file; not as a `FilePart` | async | `await read(65536)` from its current position until it returns no bytes, never line by line. | Chunked | No |
| Async iterable of `bytes`; not as a `FilePart` | async | Iterated once; each item is sent as it is yielded. | Chunked | No |

A `str` is not read as a path. `str`, `bytearray`, `memoryview`, synchronous text-mode or closed files, a path that
cannot be opened, and an async file or async iterable as a `FilePart` (HTTPX2 reads multipart files synchronously)
raise a request `DecodeError` with the reason `unencodable` before anything is sent, with the underlying failure as
`cause`. An async file is not inspected first: a text-mode or closed one fails while sending as `APIConnectionError`.

Caller files stay open, wherever the last read left them. A path the call opened is closed when the call ends; a close
failure is attached to an error already propagating, and otherwise raises `SDKError` with the reason
`cleanup_failed`. Sync calls do all file I/O on the calling thread. In async calls a path the call opens is opened,
read, and closed in a worker thread, one chunk at a time; a caller's synchronous file is read on the event loop, and
an async file where it decides. A cancelled or timed-out call waits for a running file call before it closes the file.

A retry, or a 307 or 308 redirect HTTPX2 follows, resends bytes and seeks a seekable file back to its entry position; a
failing seek raises a request `DecodeError` with the reason `body_not_replayable`. A consumed one-shot input is not
retried: the failure that would have been retried is raised. A multipart body replays when every file part can. A
failure while a file or iterable is read during sending raises `APIConnectionError` with that failure as `cause`.

### Multipart bodies

A `MultipartBody` with parts is sent through HTTPX2's `files=` encoding, its parts in their order: each `FieldPart` and
`FilePart` keeps its name, filename, media type and extra headers, and parts may repeat a name. A field's value goes
through its member's model codec, a repeated member sends a part for each item, a styled member the parts its style
gives, and a media type the member's encoding declares must cover the one a part names. A member's `style`, `explode`,
and `allowReserved` apply in OpenAPI 3.1 and 3.2 documents, whose parts carry the style's text without percent-encoding,
so a delimited value that holds its style's delimiter (`,`, a space, or `|`) raises a request `DecodeError` with the
reason `unencodable` before sending; OpenAPI 3.0 ignores them for `multipart/form-data`, and the member is written as
one without them, in its `contentType`. Generation stops for a form whose exploded object that allows other properties
shares the form with another such member, a `deepObject` member, or other properties of its own that its schema allows
with `additionalProperties` as `true` or a schema, or that its Pydantic model keeps by its configuration, such as
`--extra-fields allow`, which would write the same names, as it does for query parameters.
The SDK does not check parts against the schema. A part header HTTPX2 refuses, and a part that is not
a `FieldPart` or a `FilePart` with a string name, raises a request `DecodeError` with the reason `unencodable` before
sending. A body whose parts are all bytes is encoded once, with `Content-Length`; a body without parts, which HTTPX2
would not send, is written by the SDK as its closing boundary alone, with the `multipart/form-data` Content-Type that
names the boundary, which a server reads as a form without members. Each body gets a boundary of its own.

The type of a member decides its parts, in a `MultipartBody` and in a form-data body sent as its model alike. A
member repeats, one part for each item, when its type is an array. A value whose type has one scalar kind is text: a
string as it is, a number or a boolean as JSON writes it. A value whose type has none is one `application/json` part:
an object, a mapping, a union of a string and an object, an enum of mixed kinds, or a union of an array and another
type such as `string | string[]`, whose array is then one part rather than one for each item. A member without a
type, whose schema is `{}`, takes any value, and that value is one `application/json` part as well, a string or an
array included; an array whose items have no type has one such part for each item. A media type that the member's
`encoding` declares takes precedence. A multipart response is read by the same rule, and a part that names a JSON
media type is read as JSON; a part of a member without a type that names none is read as text.

The client sends a JSON part as a field, without a filename, and Starlette, which the generated server and FastAPI
use, answers `400` for a field part of more than 1 MiB. Send such a value as a `FilePart` with a filename, which
Starlette does not limit by size, or read the form in your own server code with a larger `max_part_size`.

The properties a schema types without declaring them, with `additionalProperties: {...}`, follow the same rule under
whatever names a body gives them, by the type of their values: an object is one `application/json` part, an array of
objects one for each item, and a union of an array and another type one part. The type is the one the model keeps them
as, in a field of its own or one it inherits from a schema combined with `allOf`, and for a model without such a field,
the type of their schema, the form's own or that of a schema it combines with `allOf`, also when `--reuse-model` makes
the form's model inherit an equal one whose schema types them otherwise. Other properties the schema allows without a
type, with `additionalProperties: {}`, `true`, or no `additionalProperties`, are each one `application/json` part, as a
member without a type is, a string or an array included. A multipart response reads typed ones by their type too. A
URL-encoded form writes them as text of that type's kind, one pair for each item of an array, and generation stops with
`A parameter value needs one unambiguous scalar kind` at the `additionalProperties` that types them when the type has
none. A URL-encoded form writes a declared member by the same rule, and stops with that message for a member without one
scalar kind, unless the member's `encoding` gives it a style or a `contentType` (see [URL-encoded members with an
encoding](#url-encoded-members-with-an-encoding)). The generated FastAPI server reads the members of form bodies, these
other properties included, by this rule too, and stops for a member or other properties without one scalar kind with the
same message at the same place. Both also refuse a URL-encoded body whose schema has `patternProperties`
(`Pattern properties have no builtin parameter encoding`) or is not an object, such as an array, a string, or
`properties` without `type: object` (`A URL-encoded value must be an object`); the server reads such a body only in the
request body mode. A form body whose schema is a union of one schema and `null` alone is written as the form of that
schema, by its members and other properties; a multipart body whose schema is a union of several schemas has no members
to write parts by, and generation stops with `needs an object schema to be sent as parts`, as the server's generation
stops for it.

A multipart response is read only when the operation declares one, with the standard library's MIME parser: a part's
bytes are kept as they arrived unless it names a transfer encoding, and a broken body, or a part that is itself a
multipart body or a message, raises `DecodeError` with the reason `invalid_framing`.

```python
from pathlib import Path

from app.client import Client
from app.client.options import RequestOptions


def upload_file(client: Client, url: str, path: Path) -> bytes:
    response = client.request_raw("PUT", url, body=path, options=RequestOptions(max_retries=2))
    return response.read()
```

### URL-encoded members with an encoding

An `application/x-www-form-urlencoded` request body's `encoding` can give a member a `style`, `explode`, or
`allowReserved`, in every OpenAPI version, and the member is then written as the query parameter that encoding
describes, as percent-encoded pairs: an object with `style: form`, the style of an encoding that names none, and
`explode: true`, its default, as the pairs of its own members, a `deepObject` as `name[key]` pairs, and `form` without
explode, `spaceDelimited`, and `pipeDelimited` as one delimited pair. These fields take precedence over a `contentType`.
A `contentType` alone writes the member as one pair of that text, or of JSON for a JSON media type; any other media
type, such as `application/xml`, stops generation with `The member content has no builtin encoding`. A style the
member's type has no form for, such as `deepObject` for an array, stops generation too, as it does for a query
parameter. Generation also stops for a form whose exploded object that allows other properties shares the form with
another such member, a `deepObject` member, or other properties of its own that its schema allows with
`additionalProperties` as `true` or a schema, or that its Pydantic model keeps by its configuration, such as
`--extra-fields allow`, which would write the same names. A form that leaves its other properties unsaid, with a model
that drops them, is written, and its exploded object takes the names no other member writes. The other members are
written as in a form without such members. The generated FastAPI server reads these members as the client writes them.

## Redirects and transport construction

Calls are sent through the native client with `send(request, stream=True)`: its `auth`, event hooks, redirect
setting, framing, and content decoding are effective. `follow_redirects` of the client, a view, or a call's
`RequestOptions` is the native boolean for that call; unset, an SDK-created client follows no redirect and an injected
one keeps its own. HTTPX2 follows redirects itself, with its method rewriting, its `max_redirects` limit
(`TooManyRedirects` raises `APIConnectionError`), and its header rules: on every redirect it replaces the `Cookie`
header of the request, a cookie parameter included, with the cookies of the client's cookie jar that match the hop, such
as one a `Set-Cookie` response header set earlier, and it drops `Authorization` across origins. The request of the
first hop carries no jar cookie, because the SDK builds it itself. Every hop consumes the same call deadline, and a
failure after a redirect was answered is never sent again.

In a package that declares security schemes, a request carrying a credential at a scheme's position other than
`Authorization` (an API key in a header, query field, or cookie, however the request came to carry it) is never
redirected: its 3xx is the final response, which the typed call raises as `APIStatusError` and `with_raw_response`
returns with its `Location`. To follow it anyway, place the credential with an `httpx2.Auth` of your own on the
injected client, which HTTPX2 runs on every request it sends:

```python
import httpx2

from app.client import Client


class ApiKey(httpx2.Auth):
    def __init__(self, key: str) -> None:
        self.key = key

    def auth_flow(self, request: httpx2.Request):
        request.headers["X-API-Key"] = self.key
        yield request


def following_client(key: str) -> Client:
    native = httpx2.Client(auth=ApiKey(key), follow_redirects=True)
    return Client(http_client=native)
```

Request event hooks and an `httpx2.Auth` of your own run after the follow decision, so they can still add a header such
as `X-API-Key` to a request sent to another origin.

The native client's `Accept-Encoding` is sent and response content codings are removed by HTTPX2; a body that does
not decode raises `DecodeError` with the reason `malformed_coding`. A streaming raw response's `iter_raw_bytes()`
yields the body as it arrived; a buffered one keeps only its decoded body. A HEAD operation's typed result stays
bodyless after a redirect.

A client the SDK creates is `httpx2.Client(timeout=httpx2.Timeout(600, connect=5))`, or its asyncio twin, with
every other HTTPX2 default. Configure TLS, proxies, pools, HTTP/2, and environment handling on an HTTPX2 client of
your own passed as `http_client`; the SDK keeps its settings, its timeout unless `timeout` is given, and its
ownership. Typed errors and exception bodies keep at most a 64 KiB prefix of an error body; buffered raw responses
and streams are not capped.

```python
from ssl import create_default_context

import httpx2

from app.client import Client


def configured_client(ca_file: str) -> tuple[Client, httpx2.Client]:
    context = create_default_context(cafile=ca_file)
    native = httpx2.Client(verify=context, limits=httpx2.Limits(max_connections=50, max_keepalive_connections=10))
    return Client(http_client=native), native
```

An injected native client keeps its own pool, proxy, and TLS settings. The root closes only the native client it
created, once; views share their root. A borrowed client's cookies, headers, and query defaults are not merged
into SDK requests; its `Accept-Encoding` is.

## Templates

The client templates come from [`--custom-template-dir`](cli-reference/template-customization.md#custom-template-dir),
as model templates do: the files of its `client` directory replace the builtin roles of the same name:
`facade.jinja2` (the package initializers and the public modules `options`, `errors`, `responses`, `auth`, `bodies`,
and `protocols`, and the webhook packages' initializers and `webhooks/keys.py`), `client.jinja2` (`_client.py` and `_async_client.py`), `resource.jinja2` (each
resource's `_sync.py` and `_async.py`), `types.jinja2` (each resource's `types/<resource>/_operations.py`),
`arguments.jinja2` (`_generated/client_arguments.py`), `operations.jinja2` (`_operations.py`), `security.jinja2`
(`_generated/security.py`), `model_bindings.jinja2` (`_generated/model_bindings.py`), `helper_plans.jinja2`
(`protocols/_plans.py`), `helpers.jinja2` (`protocols/_helpers.py` and `protocols/_async_helpers.py`),
`webhook.jinja2` (each webhook helper's module), `readme.jinja2`, and `runtime.jinja2` (the runtime reference). A
role the directory does not hold, or a custom template directory without a `client` directory, keeps its builtin
template. The builtin templates are in the `_client/templates` directory of the installed package; copy
one to start from it. Each role receives the values its builtin template uses and, as custom model templates do, the
`#all#` entry of [`--extra-template-data`](cli-reference/template-customization.md#extra-template-data); the role's
own values take precedence over the extra data.

!!! warning "Overrides are not checked against the builtin roles"

    A file of the `client` directory that is not one of these role names is ignored without a warning, so a
    misspelled or renamed role keeps its builtin template. A value that an override names and the builtin no longer
    provides, such as one that an older copy of a builtin template uses, prints as an empty string and iterates as
    nothing, as Jinja's default `Undefined` does; the values a role receives can change while client generation is
    experimental. Generation can then succeed and write a package that fails when it is imported. Reading an attribute
    of such a value, or calling it, fails the render instead, which stops the run with an `Error` that names the
    template. After each upgrade, compare your overrides with the
    current builtin templates, and in CI import the generated package, or run `datamodel-codegen --check` and your
    tests.

The templates write every module, class, function, signature, and call; they receive records of names, type
annotations, and the values of the runtime plans. Each role receives these top-level values, where `imports` is the
module's import block and the facade's `module`, which the builtin template does not use, is the module's dotted path
in the package, empty for the package itself:

| Role | Values |
| --- | --- |
| `arguments.jinja2` | `docstring`, `imports`, `records`, `keywords` |
| `client.jinja2` | `asynchronous`, `docstring`, `imports`, `type_checking`, `lazy_imports`, `defaults`, `name`, `class_docstring`, `core`, `view_keywords`, `client_keywords`, `credentials`, `create`, `scheme_credentials`, `unset`, `request_options`, `cached_property`, `raw`, `binary`, `manager`, `self_type`, `traceback`, `add_secondary`, `resources`, `protocols`, `protocols_module`, `helper_settings` |
| `facade.jinja2` | `module`, `docstring`, `future`, `imports`, `checking`, `classes`, `exports`, `lazy`, `loader`, `listing` |
| `helper_plans.jinja2` | `docstring`, `imports`, `accessors`, `plans` |
| `helpers.jinja2` | `asynchronous`, `docstring`, `imports`, `core`, `cached_property`, `namespaces`, `helpers` |
| `model_bindings.jinja2` | `imports`, `codec_imports`, `models_annotation`, `models`, `codecs` |
| `operations.jinja2` | `docstring`, `imports`, `servers`, `operations` |
| `readme.jinja2` | `package`, `public_modules`, `reference`, `signature_style`, `body_arguments`, `backend`, `model_package`, `operations`, `contracts`, `helpers`, `stream_label`, `resumes`, `sockets`, `kinds`, `compression`, `dependencies`, `security`, `capabilities`, `runtime` |
| `resource.jinja2` | `docstring`, `imports`, `core`, `cached_property`, `overload_decorator`, `views` |
| `runtime.jinja2` | `package`, `oauth`, `schemes`, `security`, `raw_bytes`, `multipart_requests`, `credentials`, `example`, `flows`, `pagination`, `polling`, `cache`, `uploads`, `streams`, `sockets`, `compression` |
| `security.jinja2` | `docstring`, `imports`, `schemes`, `root_annotation`, `root`, `operations` |
| `types.jinja2` | `docstring`, `imports`, `type_alias`, `overload_decorator`, `aliases` |
| `webhook.jinja2` | `kind`, `name`, `algorithm`, `timestamp`, `imports`, `exports`, `typevar`, `plan`, `functions` |

`resource.jinja2` receives one view for each class of a resource module, with its cached `attributes` and its
`methods`. A method has its `name`, `view` (`plain`, `metadata`, `raw`, or `streaming`), whether it is a
`coroutine`, its `docstring`, its `overloads` and `implementation` signatures, each with its `parameters` (`name`,
`annotation`, `default`) or the TypedDict it `unpacked`, and its `returns`, the keywords record it `check`s an
unpacked call with, and its `call` of the client core: the `operation`, the `parameters` tuple, and the keyword
`arguments`. The plan constants of `operations.jinja2`, `security.jinja2`, and `arguments.jinja2` have a `name`, an
`annotation`, a `constructor`, and `arguments`, each with a `keyword`, empty for a positional one, and a `value`; so
do the `plans` of `helper_plans.jinja2` and the `plan` of `webhook.jinja2`. `helper_plans.jinja2` also receives the
typed `accessors` the plans read items and results with: each has a `name`, the `data` type it reads, the type it
`returns`, its `docstring`, the `checks` that end its read early (the `value` local, the `read` it keeps, whether it
ends at `none`, the `unset` type it ends at, when there is one, and the `missing` sentinel it ends at, when there is
one), and its `result`. `helpers.jinja2` receives the helper `namespaces`, each with its `name`, `docstring`, the
`core` it takes, the core it `wrap`s that in at the root, and its `children`, and the `helpers`, each with its `name`, `docstring`, `methods`, and the `handle` class a polling
helper with remote cancellation returns. A helper method, like a function of `webhook.jinja2`, has its `name`, whether
it is a `coroutine`, its `positional` parameters and the `keywords` after `*`, what it `returns`, its `docstring`
(empty for a webhook function, whose builtin template writes its own), and the runtime `function` it returns the call
of with its `arguments`. The `keywords` may be empty, as an unsigned webhook function's are, and a template writes
`*` only when they are not. `webhook.jinja2` receives the signature `kind`
(`none`, `adapter`, or `builtin`), the helper's `name` and its signature's `algorithm`, and whether deliveries carry a
`timestamp`; `model_bindings.jinja2` receives the stdlib field maps as `models`, each with its `type` and `value`, and
the `codecs`, each with its `name`, `annotation`, `value`, and `description`. A builtin template
writes each parameter, argument, export, and plan keyword on its own line, and leaves the type annotations and plan
values on one line for the formatter.

An operation method's docstring is the `description` of its `--client-operations` entry, or, with `--use-schema-description`, the
operation's summary and description, or else its route, such as `Call GET /pets/{petId}.`, formatted as model
docstrings are, on one line with `--use-single-line-docstring`. A template that does not parse or render stops the
run with an `Error` that names the file in the custom template directory and, when Jinja knows it, the line.

## Errors

Every exception the client defines derives from `SDKError` and is imported from `client.errors`. Python's own
exceptions pass through unchanged: `TypeError` for keywords a method cannot bind, `FileExistsError` for an existing
download target without `overwrite=True`, and the native cancellation exception of a cancelled task. Each `SDKError`
constructor is keyword-only and does not validate field values. Each carries `reason`, a stable snake_case symbol or
`None`, `operation_id`, `info`, the response metadata when one arrived, `cause`, and the measurements `attempt_count`,
`elapsed`, and `request_id`. Messages name safe call metadata (the class, `operation_id`, `reason`, and a few
class-specific details), never headers or credentials. The one payload a message carries is the start of the response
body in an `APIStatusError` message, described below; treat that message as response data before you log it. A
secondary failure beside the primary error, such as a cleanup or invalidation failure, is named in the primary error's
`__notes__`, never in an attribute or in its place.

| Exception | Raised for | Fields beside the shared ones |
|---|---|---|
| `ConfigurationError` | A setting, argument, or call the client refused, including the reasons `client_closed`, `response_consumed`, and `invalid_state` | `field_path`, `reason` (`invalid_value` by default), `helper_id` |
| `APIConnectionError` | A classified I/O failure of the transport, with the native failure as `cause`; the reason is `None` for a transport failure, `delivery_unknown` when a WebSocket send or an upload append or completion may have reached the server and is never sent again, and `negotiation_failed` for a WebSocket 101 that selected no offered subprotocol | None |
| `APITimeoutError` | A subclass of `APIConnectionError`: a phase cap that expired, with the reason `phase_timeout`, or the call's or stream's total timeout, with the reason `deadline_exceeded` | None |
| `APIStatusError` | A final status the operation does not declare as a success | `status_code`, `headers`, `request_id`, `body`, `body_bytes`, `truncated` |
| `DecodeError` | A request argument its wire form cannot carry, or a response, stream event, record, or message that cannot become its declared value | `direction` (`request` or `response`), `location`, `body_bytes`, `truncated`, `media_type` |
| `AuthError` | Credential acquisition or a token exchange failed; exported only by a package whose operations take credentials | `reason`, `status_code`, `oauth_error` |

`APIStatusError` has a subclass for each common status: `BadRequestError` (400), `AuthenticationError` (401),
`PermissionDeniedError` (403), `NotFoundError` (404), `ConflictError` (409), `UnprocessableEntityError` (422),
`RateLimitError` (429), and `InternalServerError` (500 and above); any other error status raises `APIStatusError`
itself. Its message is `Error code: <status> - <start of the body>`, with at most 500 characters of the body and `...`
when it is cut. Its `body` is the payload decoded with the operation's declared error schema for that status, or the raw
bytes, at most a 64 KiB prefix, when none is declared; a body that does not decode stays raw, and the decode
failure is the `cause`. A final status declared neither as a success nor as an error, such as an undeclared 3xx or 2xx,
raises `APIStatusError` with the reason `unexpected_status`.

A request `DecodeError` has the reason `unencodable`, with the argument's path as `location` and never its value, or
`body_not_replayable` at the `location` `("body",)`. A response `DecodeError` has the reason `invalid_syntax`,
`invalid_value` when the model or schema refuses the value, `unexpected_media_type` with the response's `media_type`,
`forbidden_body`, `missing_body`, `invalid_framing`, `invalid_header` with the `location` `("header", name)`,
or `malformed_coding` for a body whose content coding does not decode. A stream event, NDJSON record, or WebSocket
message that does not decode has the reason `missing`, `null`, `type`, `value`, or `malformed`, the `location` `("event", sequence)` or `("message", sequence)` with a pointer
where a member is at fault, and at most 64 KiB of it as `body_bytes`. `AuthError` has the reason `provider_failed`, `invalid_expiry`, `oauth_error`, `timeout`, or `reauthorization_required`.
It keeps no credential material or provider description itself; the `cause` of `provider_failed` is the application's
own exception from its credential callable or token callback.

Helpers raise `ProtocolDataError`, `SessionLimitError`, `StreamInterruptedError`, and
`WebSocketClosedError`, described with each helper, and `SDKError` with the reason `store_failed` for a cache store that
fails.

---

# Migrating from fastapi-code-generator

Source: https://datamodel-code-generator.koxudaxi.dev/fastapi-code-generator-migration/

This guide is for projects that generate a FastAPI application with
[fastapi-code-generator](https://github.com/koxudaxi/fastapi-code-generator) (*fcg*, the `fastapi-codegen` command)
and want to generate it with `datamodel-codegen --generate-server fastapi` instead. It maps each fcg option and habit
to its counterpart, and lists what has no counterpart yet.

!!! warning "Experimental"

    FastAPI server generation is experimental. Its options, generated package, template values, and served
    OpenAPI document may change. See [Experimental Features](experimental.md).

Both tools read one OpenAPI document and generate the models with datamodel-code-generator. fcg 0.8.1 requires
`datamodel-code-generator>=0.61,<0.66`, so a project that generates with fcg gets the model generation of those
releases; later model fixes and options reach it through `datamodel-codegen` only.

This page assumes the [FastAPI Server Generation](fastapi-server.md) tutorial: it links to the tested examples there
instead of repeating them.

## What changes

- **Generated code and your code are separate.** fcg writes a `main.py` whose function bodies you fill in. dcg writes a
  `app/server/` package with the routes, the request handling, and one *service Protocol* (a `typing.Protocol` class) per
  group of operations. You implement the Protocols in a module of your own and pass the objects to `create_app`.
- **You can regenerate at any time.** Every file of the package is overwritten on each run and nothing in it is meant
  to be edited, so there is nothing to merge when the document changes.
- **The settings live in `pyproject.toml`.** Every option has a `[tool.datamodel-codegen]` key of the same name, so
  `datamodel-codegen` without arguments repeats the run.

## Translate the command

=== "Before: fastapi-codegen"

    ```bash
    fastapi-codegen \
      --input openapi.yaml \
      --output app \
      --generate-routers \
      --python-version 3.12
    ```

    The run writes `app/main.py`, `app/routers/<tag>.py`, `app/dependencies.py`, and `app/models.py`.

=== "After: datamodel-codegen"

    <!-- BEGIN AUTO-GENERATED DOC EXAMPLE: fastapi-code-generator-migration.command -->
    <!-- fmt: off -->

    ```bash
    datamodel-codegen \
      --input openapi.yaml \
      --input-file-type openapi \
      --openapi-scopes schemas api \
      --output-model-type pydantic_v2.BaseModel \
      --preset standard-py312-20261015 \
      --output app/models.py \
      --generate-server fastapi \
      --server-output app/server \
      --server-package app.server \
      --server-model-package app.models
    ```

    <!-- fmt: on -->

    <!-- END AUTO-GENERATED DOC EXAMPLE: fastapi-code-generator-migration.command -->

    The run writes `app/models.py` and the `app/server/` package, as the
    [tutorial](fastapi-server.md#2-generate-the-server) shows. The same settings fit in `pyproject.toml`, which is
    also on that page.

fcg's one `--output` directory splits into three settings: `--server-output` is the directory of the package,
`--server-package` its import path, and `--server-model-package` the import path of the models that `--output`
generates. fcg imported its models with `from .models`; the package imports them by this absolute path.

The command also needs:

- **Python 3.11 or later**, both to run `datamodel-codegen` and as the target of the generated code. The
  [preset](presets.md) in the command targets 3.12.
- **A Pydantic v2 backend**: `pydantic_v2.BaseModel`, or `pydantic_v2.dataclass` with `--use-missing-sentinel` and
  `--target-pydantic-version 2.14`.
- **The `api` scope**: `--openapi-scopes schemas api`, so that the models cover the parameters, bodies, and responses
  of the operations.

[Requirements](fastapi-server.md#requirements) lists all of them. The dcg command line has no short options such as
`-i` and `-o`.

## Option mapping

| fcg | dcg | Notes |
| --- | --- | --- |
| `-i`, `--input` | `--input` with `--input-file-type openapi` | One document; a directory or a list of files is refused. |
| `-o`, `--output` | `--server-output` and `--server-package` | Both are required with `--generate-server`. |
| `-m`, `--model-file` | `--output` and `--server-model-package` | `--output` is a file or a directory. A document with references between modules needs a directory. |
| `-r`, `--generate-routers` | `--server-layout routers`, the default | One router module per group. fcg's default, a single `main.py`, corresponds to `--server-layout single`: one `routes.py` and one `Service` Protocol. |
| `-t`, `--template-dir` | `--custom-template-dir`, templates in its `fastapi/` directory | Roles differ from fcg's files; see [Custom templates and visitors](#custom-templates-and-visitors). |
| `--model-template-dir` | `--custom-template-dir`, templates in its `pydantic_v2/` directory | The model templates are datamodel-code-generator's own. |
| `-c`, `--custom-visitor` | none | `--extra-template-data` passes static values to templates. |
| `--specify-tags` | none | Include the router of one group in your own app, or filter paths with `--openapi-include-paths`. |
| `-d`, `--output-model-type` | `--output-model-type` | Only `pydantic_v2.BaseModel` and `pydantic_v2.dataclass`, which needs `--use-missing-sentinel` and `--target-pydantic-version 2.14`. |
| `-p`, `--python-version` (default 3.10) | `--target-python-version`, or a preset that sets it | 3.11 or later. |
| `--include-request-argument` | `--server-include-request` | For the raw body, use `--server-body-mode request`, or `--server-body-modes` per operation. |
| `-e`, `--encoding`, `--enum-field-as-literal`, `--strict-nullable`, `--use-annotated`, `--reuse-model`, `--enable-faux-immutability`, `--disable-timestamp`, `--allow-remote-refs`, `--allow-private-network` | the same options | Every model option of dcg applies to the server's models. |

Options that dcg adds are described in [Server options](fastapi-server.md#server-options). The server target also
brings `--check`, `--watch`, `--diff-against`, [batch jobs](fastapi-server.md#batch-jobs), the
[`generate()` function](fastapi-server.md#python-api), and, from the same document,
[a Python client](python-client.md).

## Move your handlers

In fcg, the generated `main.py` holds a function for each operation, and you replace its `pass` with your logic. For the
tutorial's `getPet`, fcg 0.8.1 generates this `main.py`, shown without its other operations; the `HTTPException`
import, `PETS`, and the body of `get_pet` are yours:

<!-- fmt: off -->

```python
from __future__ import annotations

from typing import Union

from fastapi import FastAPI, HTTPException, Path

from .models import Error, Pet

app = FastAPI(
    title='Pets',
    version='1.0',
    servers=[{'url': 'http://localhost:8000'}],
)

PETS: dict[int, Pet] = {}


@app.get(
    '/pets/{petId}',
    response_model=Pet,
    responses={'404': {'model': Error}},
    tags=['pets'],
)
def get_pet(pet_id: int = Path(..., alias='petId')) -> Union[Pet, Error]:
    if (pet := PETS.get(pet_id)) is None:
        raise HTTPException(status_code=404, detail=f'Pet {pet_id} not found')
    return pet
```

<!-- fmt: on -->

In dcg, the same logic is the method `PetStore.get_pet` of a class in your own module, which the
[quick start](fastapi-server.md#4-implement-the-operations) shows next to `list_pets` and `create_pet`. Moving a
function takes these steps:

- **Collect the methods in a class.** Subclass the Protocol of the group, `PetsService` for the `pets` tag, and pass an
  object of it to `create_app(pets=...)`. The decorator, the path, `response_model`, and `tags` are generated.
- **Keep the names.** A method is named after its `operationId` in snake case, as fcg names a function. See
  [How methods and arguments are named](fastapi-server.md#how-methods-and-arguments-are-named).
- **Drop the FastAPI defaults.** A method takes the parameters and the body as keyword arguments, already validated by
  the models, so `Path(...)`, `Query(...)`, and `Depends(...)` disappear from the signature. The arguments follow the
  naming of model fields: the quick start's preset turns on snake case, and without it you pass `--snake-case-field`.
- **Return the primary response, or an `HTTPResult`.** A bare return value is the model of the primary response. For
  another declared status, such as the `404` above, return an `HTTPResult`, which the package validates with the
  response's model; see [Return values and `HTTPResult`](fastapi-server.md#return-values-and-httpresult).
- **Keep `HTTPException` for undocumented errors.** It answers FastAPI's `{"detail": ...}` body, as in fcg; see
  [Raise errors](fastapi-server.md#raise-errors).
- **Choose the handler mode in the settings.** fcg users turn a function into a coroutine function by editing it. In
  dcg, `--server-handler-mode async` or `--server-handler-modes` makes the method a coroutine function; see
  [Async methods](fastapi-server.md#async-methods).

The method's docstring is `Handle GET /pets/{petId}.` by default, where fcg used the operation's summary.
`--use-schema-description` writes the summary and description of the operation instead.

## Dependencies, security, uploads, and raw requests

### Per-request dependencies

fcg handlers declare what they need in their signature, such as `db: Session = Depends(get_db)`. A generated method
has a fixed signature, and the values that the `dependencies` and `operation_dependencies` of `create_app` and
`build_router` return never reach it.

Pass long-lived objects, such as a database client, to the constructor of your service class. For a value of the
request, generate with `--server-include-request` and let a dependency put it in `request.state`; the
[how-to](fastapi-server.md#the-request-and-per-request-dependencies) shows both. Dependencies still run before the
method, so they fit checks and side effects such as auditing.

### Security

fcg projects secure operations in their templates, with a `Depends` in each function. In dcg, the document describes
the security: declare `securitySchemes` and `security` in it, and the package gets a `security.py` with one FastAPI
dependency for each scheme. `create_app` then takes an `authorize(requirement_sets, credentials)` callback, and what
it returns reaches the method as the keyword `principal`. [Authenticate requests](fastapi-server.md#authenticate-requests)
walks through it with a bearer token.

### Uploads

fcg passes a file part of a `multipart/form-data` body as an `UploadFile`. In dcg, the part arrives as `bytes` in the
body model, so the file name and the content type are lost; see [Accept uploads](fastapi-server.md#accept-uploads).
When you need them, generate the operation with `--server-body-modes` set to `request` (or `--server-body-mode request`
for every operation) and read the form from the raw request.

### The raw request

`--include-request-argument` of fcg corresponds to `--server-include-request`: every method receives the Starlette
request as the keyword `request`. To receive the request instead of a validated body, use `--server-body-mode request`
or `--server-body-modes`, whose keys are operation references; see
[Per-operation settings](fastapi-server.md#per-operation-settings).

## Custom templates and visitors

dcg's model templates are the same mechanism that `--model-template-dir` of fcg used, so a template that overrides a
model usually carries over: put it in `pydantic_v2/` of the directory that `--custom-template-dir` names, and compare
it with the current builtin template. Model templates must keep the class and field names, because the server binds
each operation to them.

The server templates cannot be ported one to one. fcg renders one template with a list of `operations`. dcg renders a
fixed set of *roles*, each a file of the `fastapi/` directory of the template directory, with the values of that
role:

| Role | Generates |
| --- | --- |
| `application.jinja2` | `application.py`: `create_app`, `build_router` |
| `router.jinja2` | the routes module, or each router module |
| `services.jinja2` | `services.py`: the service Protocols |
| `security.jinja2` | `security.py` |
| `contract.jinja2` | `_generated/contract.py` |
| `facade.jinja2` | the package initializers |
| `openapi.jinja2` | `_generated/openapi.py` |
| `readme.jinja2` | `README.md` |

A role the directory does not hold keeps its builtin template. A file in `fastapi/` that is not a role is ignored
without a message, so check the file name when an override has no effect. The values of every role, which can change
while the target is experimental, are in [Templates](fastapi-server.md#templates).

Most reasons to customize an fcg template have a built-in answer: security is generated from the document, async is a
setting, and the request is an option. For the rest, rewrite the override from the builtin template of the role.

fcg's custom visitors compute extra variables for the templates from the parsed document. dcg has no visitors.
`--extra-template-data` passes static values to every role under the `#all#` key, so a script of your own can compute
them and write the JSON file before the run.

## Migrate incrementally

You do not have to move an application at once. Generate the package beside the old code, with another
`--server-output` and `--server-package` than any module that you already have, and include the router of a group in
your existing FastAPI application. With the default `routers` layout, each router module `app/server/routers/<group>.py` has its own `build_router`, which
takes the service of that group only, so you move one group at a time. The old routes keep working. fcg wrote
`models.py` into its `--output` directory too: if that is `app`, point `--output` and `--server-model-package` at another
module so that the two models do not overwrite each other.

[Use your own FastAPI app](fastapi-server.md#use-your-own-fastapi-app) shows `build_router` in an application of your
own. Three things apply while old and new routes share an application:

- **Registration order decides.** FastAPI uses the first route that matches a request, so remove the old function of an
  operation, or register the new router first, when the router takes it over.
- **Leave `serve_source_openapi` for the end.** It makes `/openapi.json` serve the generated document, which lists every
  generated path and none of the old routes. Until the old routes are gone, FastAPI's own document describes both.
- **Register `validation_error_handler` last.** It applies to the whole application, so it also changes the `422`
  bodies of the old routes.

To generate only the operations that you moved, pass `--openapi-include-paths`; see
[Server options](fastapi-server.md#server-options).

## Regenerate in CI

Run the generation command again whenever the document changes. The Protocols change with the operations, and type
checkers point at the implementations to update.

- **Check in CI.** `--check` renders everything without writing it and exits with 0 when nothing would change, 1 when a
  file would change, and 2 for an error. A run without a timestamp, which `--disable-timestamp` or a preset gives you,
  reproduces every byte; see [Check in CI](fastapi-server.md#check-in-ci).
- **Delete stale router modules.** Generation overwrites every generated file but does not delete one. After you remove
  a tag from the document, its `app/server/routers/<group>.py` stays, and `--check` lists it as no longer generated. Delete
  it by hand.
- **Keep your code outside the package**, in the `app/services` modules that `app/server/main.py` imports, which generation writes
  once with stubs. `--check` also reports any other `.py` file under `--server-output`.
- **Watch the document.** `--watch` regenerates on every change of the input and needs the `watch` extra,
  `datamodel-code-generator[watch]`; see [Compare and watch](fastapi-server.md#compare-and-watch).

## Behaviour differences

- **Nothing generated is editable.** Every file under `--server-output` is overwritten, so your code lives outside the
  package.
- **Methods are keyword-only** and return the primary response model, an `HTTPResult`, or a Starlette `Response`.
- **Operations are grouped by their first tag.** An operation without a tag goes to the `default` group, which makes
  `DefaultService` and the `default=` argument of `create_app`. fcg's modular output dropped such operations.
- **There is no `GET /` route.** fcg's modular `main.py` added a "Gateway of the App" route; the package serves only
  the paths of the document.
- **`/openapi.json` serves your document**, not the one FastAPI derives from the routes. `create_app(...,
  source_openapi=False)` serves FastAPI's again. See [Served OpenAPI document](fastapi-server.md#served-openapi-document).
- **`422` bodies omit `input` and `ctx`**, so the response does not return the rejected value; see
  [Production settings](fastapi-server.md#production-settings).
- **Literal paths come before templated paths**, so `/pets/me` is registered before `/pets/{petId}`. fcg sorted the
  routes by path.
- **The models file has more names.** A schema written inline takes a derived name such as `PetsGetResponse`, and
  parameters get type aliases. Declare schemas under `components` to name them yourself, as the tutorial does.
- **Generation is stricter.** A path placeholder without a declared path parameter stops the run, where fcg ignored it.
  A path parameter that names no placeholder of its operation's path is refused with an error instead of being
  generated, and every other path parameter is required even when the document leaves out `required` or declares it
  `false`.
- **Modular references need a directory.** When the document references schemas in other modules, `--output` must name
  a directory, not a file.

## Not available yet

- **Tag filtering (`--specify-tags`).** Include the router of a group in your own app with its `build_router`, or leave
  paths out with `--openapi-include-paths`. `create_app` takes every group.
- **Custom visitors (`--custom-visitor`).** Pass static values with `--extra-template-data`.
- **`UploadFile`.** A file part is `bytes`. Use `--server-body-mode request` or `--server-body-modes` and read the form
  yourself.
- **Python 3.10 targets.** A target below 3.11, and running `datamodel-codegen` on 3.10, are refused. Keep fcg for such
  a project until it moves to 3.11.
- **Backends other than Pydantic v2.** fcg also accepts `dataclasses.dataclass`, `typing.TypedDict`, and
  `msgspec.Struct`; the server target does not, and has no workaround.

---

# CLI Reference

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/

This documentation is auto-generated from test cases.

🔍 **[Quick Reference](quick-reference.md)** - All options on one page for Ctrl+F search

## 📂 Categories

| Category | Options | Description |
|----------|---------|-------------|
| 📁 [Base Options](base-options.md) | 13 | Input/output configuration |
| 🔧 [Typing Customization](typing-customization.md) | 35 | Type annotation and import behavior |
| 🏷️ [Field Customization](field-customization.md) | 29 | Field naming and docstring behavior |
| 🏗️ [Model Customization](model-customization.md) | 46 | Model generation behavior |
| 🎨 [Template Customization](template-customization.md) | 27 | Output formatting and custom rendering |
| 📘 [OpenAPI-only Options](openapi-only-options.md) | 8 | OpenAPI-specific features |
| 📋 [GraphQL-only Options](graphql-only-options.md) | 1 |  |
| ⚙️ [General Options](general-options.md) | 24 | Utilities and meta options |
| 🚀 [Target Generation Options](target-generation-options.md) | 25 | Server and client generation with the models (experimental) |
| 📝 [Utility Options](utility-options.md) | 15 | Help, version, debug options |

## 🎯 Focused Topics

Use these pages when you know the workflow area but not the exact option name.

| Topic | Options | Groups |
|-------|---------|--------|
| [Model Customization](topics/model-customization.md) | 23 | Model Naming, Model Reuse, Model Shape, Root Model |
| [Template Customization](topics/template-customization.md) | 21 | Custom Templates, Generated Output, Imports, Output Formatting |
| [Typing Customization](topics/typing-customization.md) | 24 | Imports, Collection Types, Type Alias, Type Mapping, Type Syntax |
| [OpenAPI](topics/openapi.md) | 7 | OpenAPI Naming, OpenAPI Paths, OpenAPI Scopes, Read Only Write Only |

## 🔗 Option Relationships

These links are generated from CLI option metadata and summarize options that imply, require, or conflict with other options.

| Source | Kind | Condition | Target | Note |
|--------|------|-----------|--------|------|
| [`--use-annotated`](typing-customization.md#use-annotated) | Implies | Always | [`--field-constraints`](field-customization.md#field-constraints) enabled | - |
| [`--use-specialized-enum`](typing-customization.md#use-specialized-enum) | Requires | Always | [`--target-python-version`](model-customization.md#target-python-version) = `3.11+` | `--use-specialized-enum` requires `--target-python-version` 3.11 or higher. |
| [`--use-type-alias-type`](typing-customization.md#use-type-alias-type) | Implies | Always | [`--use-type-alias`](typing-customization.md#use-type-alias) enabled | - |
| [`--original-field-name-delimiter`](field-customization.md#original-field-name-delimiter) | Requires | Always | [`--snake-case-field`](field-customization.md#snake-case-field) enabled | `--original-field-name-delimiter` can not be used without `--snake-case-field`. |
| [`--allow-extra-fields`](model-customization.md#allow-extra-fields) | Implies | Always | [`--extra-fields`](field-customization.md#extra-fields) = `allow` | - |
| [`--collapse-root-models-name-strategy`](model-customization.md#collapse-root-models-name-strategy) | Requires | Always | [`--collapse-root-models`](model-customization.md#collapse-root-models) enabled | `--collapse-root-models-name-strategy` requires `--collapse-root-models`. |
| [`--keyword-only`](model-customization.md#keyword-only) | Requires | Always | [`--target-python-version`](model-customization.md#target-python-version) = `3.10+` | `--keyword-only` requires `--target-python-version` 3.10 or higher for dataclasses. |
| [`--output-model-type`](model-customization.md#output-model-type) | Implies | `--output-model-type` = `msgspec.Struct` | [`--use-annotated`](typing-customization.md#use-annotated) enabled | - |
| [`--parent-scoped-naming`](model-customization.md#parent-scoped-naming) | Implies | Always | [`--naming-strategy`](model-customization.md#naming-strategy) = `parent-prefixed` | - |
| [`--reuse-scope`](model-customization.md#reuse-scope) | Requires | `--reuse-scope` = `tree` | [`--reuse-model`](model-customization.md#reuse-model) enabled | `--reuse-scope=tree` has no effect without `--reuse-model`. |
| [`--union-mode`](model-customization.md#union-mode) | Requires | Always | [`--output-model-type`](model-customization.md#output-model-type) = `pydantic_v2.BaseModel` | `--union-mode` is only supported for `--output-model-type pydantic_v2.BaseModel`. |
| [`--use-missing-sentinel`](model-customization.md#use-missing-sentinel) | Implies | Always | [`--target-pydantic-version`](model-customization.md#target-pydantic-version) = `2.12` | - |
| [`--use-missing-sentinel`](model-customization.md#use-missing-sentinel) | Requires | Always | [`--output-model-type`](model-customization.md#output-model-type) | `--use-missing-sentinel` is only supported for `--output-model-type pydantic_v2.BaseModel` or `pydantic_v2.dataclass`. |
| [`--custom-file-header`](template-customization.md#custom-file-header) | Conflicts | Always | [`--custom-file-header-path`](template-customization.md#custom-file-header-path) | `--custom-file-header` can not be used with `--custom-file-header-path`. |
| [`--custom-file-header-path`](template-customization.md#custom-file-header-path) | Conflicts | Always | [`--custom-file-header`](template-customization.md#custom-file-header) | `--custom-file-header-path` can not be used with `--custom-file-header`. |
| [`--all-exports-collision-strategy`](general-options.md#all-exports-collision-strategy) | Requires | Always | [`--all-exports-scope`](general-options.md#all-exports-scope) = `recursive` | `--all-exports-collision-strategy` can only be used with `--all-exports-scope=recursive`. |
| [`--diff-against`](general-options.md#diff-against) | Requires | Always | [`--input`](base-options.md#input) | `--diff-against` requires --input with the current local schema path. |
| [`--diff-against`](general-options.md#diff-against) | Requires | Always | [`--output`](base-options.md#output) | `--diff-against` requires --output to select file or directory output layout. |
| [`--diff-against`](general-options.md#diff-against) | Conflicts | Always | [`--check`](general-options.md#check) | - |
| [`--diff-against`](general-options.md#diff-against) | Conflicts | Always | [`--watch`](general-options.md#watch) | - |
| [`--diff-against`](general-options.md#diff-against) | Conflicts | Always | [`--url`](base-options.md#url) | - |
| [`--diff-against`](general-options.md#diff-against) | Conflicts | Always | [`--input-model`](base-options.md#input-model) | - |
| [`--diff-against`](general-options.md#diff-against) | Conflicts | Always | [`--emit-model-metadata`](base-options.md#emit-model-metadata) | - |
| [`--diff-against`](general-options.md#diff-against) | Conflicts | Always | [`--fail-on-multi-module-stdout`](general-options.md#fail-on-multi-module-stdout) | - |
| [`--diff-against`](general-options.md#diff-against) | Conflicts | Always | `--job` | `--diff-against` compares one profile or input and cannot run named jobs. |
| [`--diff-against`](general-options.md#diff-against) | Conflicts | Always | `--all-jobs` | `--diff-against` compares one profile or input and cannot run named jobs. |
| [`--locked`](general-options.md#locked) | Conflicts | Always | [`--update-lock`](general-options.md#update-lock) | - |
| [`--update-lock`](general-options.md#update-lock) | Conflicts | Always | [`--locked`](general-options.md#locked) | - |
| [`--client-body-arguments`](target-generation-options.md#client-body-arguments) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-body-arguments` requires `--generate-client httpx2`. |
| [`--client-default-base-url`](target-generation-options.md#client-default-base-url) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-default-base-url` requires `--generate-client httpx2`. |
| [`--client-model-package`](target-generation-options.md#client-model-package) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-model-package` requires `--generate-client httpx2`. |
| [`--client-operations`](target-generation-options.md#client-operations) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-operations` requires `--generate-client httpx2`. |
| [`--client-output`](target-generation-options.md#client-output) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-output` requires `--generate-client httpx2`. |
| [`--client-package`](target-generation-options.md#client-package) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-package` requires `--generate-client httpx2`. |
| [`--client-protocols`](target-generation-options.md#client-protocols) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-protocols` requires `--generate-client httpx2`. |
| [`--client-resource-names`](target-generation-options.md#client-resource-names) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-resource-names` requires `--generate-client httpx2`. |
| [`--client-server-base-url`](target-generation-options.md#client-server-base-url) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-server-base-url` requires `--generate-client httpx2`. |
| [`--client-signature-style`](target-generation-options.md#client-signature-style) | Requires | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--client-signature-style` requires `--generate-client httpx2`. |
| [`--generate-client`](target-generation-options.md#generate-client) | Requires | Always | [`--client-output`](target-generation-options.md#client-output) | `--generate-client` requires `--client-output`. |
| [`--generate-client`](target-generation-options.md#generate-client) | Requires | Always | [`--client-package`](target-generation-options.md#client-package) | `--generate-client` requires `--client-package`. |
| [`--generate-client`](target-generation-options.md#generate-client) | Requires | Always | [`--client-model-package`](target-generation-options.md#client-model-package) | `--generate-client` requires `--client-model-package`. |
| [`--generate-client`](target-generation-options.md#generate-client) | Requires | Always | [`--input-file-type`](base-options.md#input-file-type) = `openapi` | `--generate-client` requires `--input-file-type openapi`. |
| [`--generate-client`](target-generation-options.md#generate-client) | Conflicts | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--generate-client` can not be used with `--generate-server`. |
| [`--generate-server`](target-generation-options.md#generate-server) | Requires | Always | [`--server-output`](target-generation-options.md#server-output) | `--generate-server` requires `--server-output`. |
| [`--generate-server`](target-generation-options.md#generate-server) | Requires | Always | [`--server-package`](target-generation-options.md#server-package) | `--generate-server` requires `--server-package`. |
| [`--generate-server`](target-generation-options.md#generate-server) | Requires | Always | [`--server-model-package`](target-generation-options.md#server-model-package) | `--generate-server` requires `--server-model-package`. |
| [`--generate-server`](target-generation-options.md#generate-server) | Requires | Always | [`--input-file-type`](base-options.md#input-file-type) = `openapi` | `--generate-server` requires `--input-file-type openapi`. |
| [`--generate-server`](target-generation-options.md#generate-server) | Conflicts | Always | [`--generate-client`](target-generation-options.md#generate-client) | `--generate-server` can not be used with `--generate-client`. |
| [`--server-body-mode`](target-generation-options.md#server-body-mode) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-body-mode` requires `--generate-server fastapi`. |
| [`--server-body-modes`](target-generation-options.md#server-body-modes) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-body-modes` requires `--generate-server fastapi`. |
| [`--server-handler-mode`](target-generation-options.md#server-handler-mode) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-handler-mode` requires `--generate-server fastapi`. |
| [`--server-handler-modes`](target-generation-options.md#server-handler-modes) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-handler-modes` requires `--generate-server fastapi`. |
| [`--server-include-request`](target-generation-options.md#server-include-request) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-include-request` requires `--generate-server fastapi`. |
| [`--server-layout`](target-generation-options.md#server-layout) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-layout` requires `--generate-server fastapi`. |
| [`--server-model-package`](target-generation-options.md#server-model-package) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-model-package` requires `--generate-server fastapi`. |
| [`--server-operation-names`](target-generation-options.md#server-operation-names) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-operation-names` requires `--generate-server fastapi`. |
| [`--server-output`](target-generation-options.md#server-output) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-output` requires `--generate-server fastapi`. |
| [`--server-package`](target-generation-options.md#server-package) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-package` requires `--generate-server fastapi`. |
| [`--server-parameter-names`](target-generation-options.md#server-parameter-names) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-parameter-names` requires `--generate-server fastapi`. |
| [`--server-primary-responses`](target-generation-options.md#server-primary-responses) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-primary-responses` requires `--generate-server fastapi`. |
| [`--server-router-names`](target-generation-options.md#server-router-names) | Requires | Always | [`--generate-server`](target-generation-options.md#generate-server) | `--server-router-names` requires `--generate-server fastapi`. |

## All Options

**Jump to:** [A](#a) · [B](#b) · [C](#c) · [D](#d) · [E](#e) · [F](#f) · [G](#g) · [H](#h) · [I](#i) · [J](#j) · [K](#k) · [L](#l) · [M](#m) · [N](#n) · [O](#o) · [P](#p) · [R](#r) · [S](#s) · [T](#t) · [U](#u) · [V](#v) · [W](#w)


### A {#a}

- [`--additional-imports`](template-customization.md#additional-imports)
- [`--alias-generator`](model-customization.md#alias-generator)
- [`--aliases`](field-customization.md#aliases)
- [`--all-exports-collision-strategy`](general-options.md#all-exports-collision-strategy)
- [`--all-exports-scope`](general-options.md#all-exports-scope)
- [`--all-jobs`](utility-options.md#all-jobs)
- [`--allof-class-hierarchy`](typing-customization.md#allof-class-hierarchy)
- [`--allof-merge-mode`](typing-customization.md#allof-merge-mode)
- [`--allow-extra-fields`](model-customization.md#allow-extra-fields)
- [`--allow-leading-underscore-class-name`](model-customization.md#allow-leading-underscore-class-name)
- [`--allow-population-by-field-name`](model-customization.md#allow-population-by-field-name)
- [`--allow-private-network`](general-options.md#allow-private-network)
- [`--allow-remote-refs`](general-options.md#allow-remote-refs)

### B {#b}

- [`--base-class`](model-customization.md#base-class)
- [`--base-class-map`](model-customization.md#base-class-map)

### C {#c}

- [`--capitalize-enum-members`](field-customization.md#capitalize-enum-members)
- [`--check`](general-options.md#check)
- [`--class-decorators`](template-customization.md#class-decorators)
- [`--class-name`](model-customization.md#class-name)
- [`--class-name-affix-scope`](model-customization.md#class-name-affix-scope)
- [`--class-name-prefix`](model-customization.md#class-name-prefix)
- [`--class-name-suffix`](model-customization.md#class-name-suffix)
- [`--client-body-arguments`](target-generation-options.md#client-body-arguments)
- [`--client-default-base-url`](target-generation-options.md#client-default-base-url)
- [`--client-model-package`](target-generation-options.md#client-model-package)
- [`--client-operations`](target-generation-options.md#client-operations)
- [`--client-output`](target-generation-options.md#client-output)
- [`--client-package`](target-generation-options.md#client-package)
- [`--client-protocols`](target-generation-options.md#client-protocols)
- [`--client-resource-names`](target-generation-options.md#client-resource-names)
- [`--client-server-base-url`](target-generation-options.md#client-server-base-url)
- [`--client-signature-style`](target-generation-options.md#client-signature-style)
- [`--collapse-reuse-models`](model-customization.md#collapse-reuse-models)
- [`--collapse-root-models`](model-customization.md#collapse-root-models)
- [`--collapse-root-models-name-strategy`](model-customization.md#collapse-root-models-name-strategy)
- [`--custom-file-header`](template-customization.md#custom-file-header)
- [`--custom-file-header-mode`](template-customization.md#custom-file-header-mode)
- [`--custom-file-header-path`](template-customization.md#custom-file-header-path)
- [`--custom-formatters`](template-customization.md#custom-formatters)
- [`--custom-formatters-kwargs`](template-customization.md#custom-formatters-kwargs)
- [`--custom-template-dir`](template-customization.md#custom-template-dir)

### D {#d}

- [`--dataclass-arguments`](model-customization.md#dataclass-arguments)
- [`--debug`](utility-options.md#debug)
- [`--default-values`](field-customization.md#default-values)
- [`--deserialize-default-values`](field-customization.md#deserialize-default-values)
- [`--diff-against`](general-options.md#diff-against)
- [`--disable-appending-item-suffix`](template-customization.md#disable-appending-item-suffix)
- [`--disable-future-imports`](typing-customization.md#disable-future-imports)
- [`--disable-timestamp`](template-customization.md#disable-timestamp)
- [`--disable-warnings`](general-options.md#disable-warnings)
- [`--duplicate-name-suffix`](model-customization.md#duplicate-name-suffix)

### E {#e}

- [`--emit-model-metadata`](base-options.md#emit-model-metadata)
- [`--empty-enum-field-name`](field-customization.md#empty-enum-field-name)
- [`--enable-command-header`](template-customization.md#enable-command-header)
- [`--enable-faux-immutability`](model-customization.md#enable-faux-immutability)
- [`--enable-generated-header-marker`](template-customization.md#enable-generated-header-marker)
- [`--enable-version-header`](template-customization.md#enable-version-header)
- [`--encoding`](base-options.md#encoding)
- [`--enum-field-as-literal`](typing-customization.md#enum-field-as-literal)
- [`--enum-field-as-literal-map`](typing-customization.md#enum-field-as-literal-map)
- [`--external-ref-mapping`](base-options.md#external-ref-mapping)
- [`--extra-fields`](field-customization.md#extra-fields)
- [`--extra-template-data`](template-customization.md#extra-template-data)

### F {#f}

- [`--fail-on-multi-module-stdout`](general-options.md#fail-on-multi-module-stdout)
- [`--field-constraints`](field-customization.md#field-constraints)
- [`--field-extra-keys`](field-customization.md#field-extra-keys)
- [`--field-extra-keys-without-x-prefix`](field-customization.md#field-extra-keys-without-x-prefix)
- [`--field-include-all-keys`](field-customization.md#field-include-all-keys)
- [`--field-type-collision-strategy`](field-customization.md#field-type-collision-strategy)
- [`--force-optional`](model-customization.md#force-optional)
- [`--formatters`](template-customization.md#formatters)
- [`--frozen-dataclasses`](model-customization.md#frozen-dataclasses)

### G {#g}

- [`--generate-cli-command`](general-options.md#generate-cli-command)
- [`--generate-client`](target-generation-options.md#generate-client)
- [`--generate-prompt`](utility-options.md#generate-prompt)
- [`--generate-pyproject-config`](general-options.md#generate-pyproject-config)
- [`--generate-schema-validators`](template-customization.md#generate-schema-validators)
- [`--generate-server`](target-generation-options.md#generate-server)
- [`--graphql-no-typename`](graphql-only-options.md#graphql-no-typename)

### H {#h}

- [`--help`](utility-options.md#help)
- [`--http-backend`](base-options.md#http-backend)
- [`--http-headers`](general-options.md#http-headers)
- [`--http-ignore-tls`](general-options.md#http-ignore-tls)
- [`--http-local-ref-path`](general-options.md#http-local-ref-path)
- [`--http-query-parameters`](general-options.md#http-query-parameters)
- [`--http-timeout`](general-options.md#http-timeout)

### I {#i}

- [`--ignore-enum-constraints`](typing-customization.md#ignore-enum-constraints)
- [`--ignore-pyproject`](general-options.md#ignore-pyproject)
- [`--import-overrides`](typing-customization.md#import-overrides)
- [`--include-path-parameters`](openapi-only-options.md#include-path-parameters)
- [`--infer-union-variant-names`](field-customization.md#infer-union-variant-names)
- [`--input`](base-options.md#input)
- [`--input-file-type`](base-options.md#input-file-type)
- [`--input-model`](base-options.md#input-model)
- [`--input-model-ref-strategy`](base-options.md#input-model-ref-strategy)
- [`--install-skill`](utility-options.md#install-skill)

### J {#j}

- [`--job`](utility-options.md#job)

### K {#k}

- [`--keep-model-order`](model-customization.md#keep-model-order)
- [`--keyword-only`](model-customization.md#keyword-only)

### L {#l}

- [`--list-deprecations`](utility-options.md#list-deprecations)
- [`--list-experimental`](utility-options.md#list-experimental)
- [`--locked`](general-options.md#locked)
- [`--lockfile`](general-options.md#lockfile)

### M {#m}

- [`--model-extra-keys`](model-customization.md#model-extra-keys)
- [`--model-extra-keys-without-x-prefix`](model-customization.md#model-extra-keys-without-x-prefix)
- [`--model-name-map`](model-customization.md#model-name-map)
- [`--module-split-mode`](general-options.md#module-split-mode)

### N {#n}

- [`--naming-strategy`](model-customization.md#naming-strategy)
- [`--no-alias`](field-customization.md#no-alias)
- [`--no-color`](utility-options.md#no-color)
- [`--no-deserialize-default-values`](field-customization.md#no-deserialize-default-values)
- [`--no-treat-dot-as-module`](template-customization.md#no-treat-dot-as-module)
- [`--no-use-closed-typed-dict`](typing-customization.md#no-use-closed-typed-dict)
- [`--no-use-specialized-enum`](typing-customization.md#no-use-specialized-enum)
- [`--no-use-standard-collections`](typing-customization.md#no-use-standard-collections)
- [`--no-use-type-checking-imports`](template-customization.md#no-use-type-checking-imports)
- [`--no-use-union-operator`](typing-customization.md#no-use-union-operator)

### O {#o}

- [`--openapi-include-info-version`](openapi-only-options.md#openapi-include-info-version)
- [`--openapi-include-paths`](openapi-only-options.md#openapi-include-paths)
- [`--openapi-scopes`](openapi-only-options.md#openapi-scopes)
- [`--original-field-name-delimiter`](field-customization.md#original-field-name-delimiter)
- [`--output`](base-options.md#output)
- [`--output-date-class`](typing-customization.md#output-date-class)
- [`--output-datetime-class`](typing-customization.md#output-datetime-class)
- [`--output-format`](utility-options.md#output-format)
- [`--output-format-json-schema`](utility-options.md#output-format-json-schema)
- [`--output-model-type`](model-customization.md#output-model-type)
- [`--overwrite-skill`](utility-options.md#overwrite-skill)

### P {#p}

- [`--parent-scoped-naming`](model-customization.md#parent-scoped-naming)
- [`--preset`](base-options.md#preset)
- [`--profile`](utility-options.md#profile)

### R {#r}

- [`--read-only-write-only-model-type`](openapi-only-options.md#read-only-write-only-model-type)
- [`--remove-special-field-name-prefix`](field-customization.md#remove-special-field-name-prefix)
- [`--reuse-model`](model-customization.md#reuse-model)
- [`--reuse-scope`](model-customization.md#reuse-scope)

### S {#s}

- [`--schema-validator-base-class-name`](template-customization.md#schema-validator-base-class-name)
- [`--schema-validator-type`](template-customization.md#schema-validator-type)
- [`--schema-version`](base-options.md#schema-version)
- [`--schema-version-mode`](base-options.md#schema-version-mode)
- [`--serialization-aliases`](field-customization.md#serialization-aliases)
- [`--server-body-mode`](target-generation-options.md#server-body-mode)
- [`--server-body-modes`](target-generation-options.md#server-body-modes)
- [`--server-handler-mode`](target-generation-options.md#server-handler-mode)
- [`--server-handler-modes`](target-generation-options.md#server-handler-modes)
- [`--server-include-request`](target-generation-options.md#server-include-request)
- [`--server-layout`](target-generation-options.md#server-layout)
- [`--server-model-package`](target-generation-options.md#server-model-package)
- [`--server-operation-names`](target-generation-options.md#server-operation-names)
- [`--server-output`](target-generation-options.md#server-output)
- [`--server-package`](target-generation-options.md#server-package)
- [`--server-parameter-names`](target-generation-options.md#server-parameter-names)
- [`--server-primary-responses`](target-generation-options.md#server-primary-responses)
- [`--server-router-names`](target-generation-options.md#server-router-names)
- [`--set-default-enum-member`](field-customization.md#set-default-enum-member)
- [`--shared-module-name`](general-options.md#shared-module-name)
- [`--skill-scope`](utility-options.md#skill-scope)
- [`--skip-root-model`](model-customization.md#skip-root-model)
- [`--snake-case-field`](field-customization.md#snake-case-field)
- [`--special-field-name-prefix`](field-customization.md#special-field-name-prefix)
- [`--strict-dotted-module-names`](template-customization.md#strict-dotted-module-names)
- [`--strict-nullable`](model-customization.md#strict-nullable)
- [`--strict-refs`](general-options.md#strict-refs)
- [`--strict-types`](typing-customization.md#strict-types)
- [`--strip-default-none`](model-customization.md#strip-default-none)

### T {#t}

- [`--target-pydantic-version`](model-customization.md#target-pydantic-version)
- [`--target-python-version`](model-customization.md#target-python-version)
- [`--treat-dot-as-module`](template-customization.md#treat-dot-as-module)
- [`--type-mappings`](typing-customization.md#type-mappings)
- [`--type-overrides`](typing-customization.md#type-overrides)

### U {#u}

- [`--union-mode`](model-customization.md#union-mode)
- [`--update-lock`](general-options.md#update-lock)
- [`--url`](base-options.md#url)
- [`--use-annotated`](typing-customization.md#use-annotated)
- [`--use-attribute-docstrings`](field-customization.md#use-attribute-docstrings)
- [`--use-closed-typed-dict`](typing-customization.md#use-closed-typed-dict)
- [`--use-decimal-for-multiple-of`](typing-customization.md#use-decimal-for-multiple-of)
- [`--use-default`](model-customization.md#use-default)
- [`--use-default-factory-for-optional-nested-models`](model-customization.md#use-default-factory-for-optional-nested-models)
- [`--use-default-kwarg`](model-customization.md#use-default-kwarg)
- [`--use-double-quotes`](template-customization.md#use-double-quotes)
- [`--use-enum-values-in-discriminator`](field-customization.md#use-enum-values-in-discriminator)
- [`--use-exact-imports`](template-customization.md#use-exact-imports)
- [`--use-field-description`](field-customization.md#use-field-description)
- [`--use-field-description-example`](field-customization.md#use-field-description-example)
- [`--use-frozen-field`](model-customization.md#use-frozen-field)
- [`--use-generic-base-class`](model-customization.md#use-generic-base-class)
- [`--use-generic-container-types`](typing-customization.md#use-generic-container-types)
- [`--use-inline-field-description`](field-customization.md#use-inline-field-description)
- [`--use-missing-sentinel`](model-customization.md#use-missing-sentinel)
- [`--use-msgspec-nullable-enum-alias`](model-customization.md#use-msgspec-nullable-enum-alias)
- [`--use-msgspec-tagged-unions`](model-customization.md#use-msgspec-tagged-unions)
- [`--use-non-positive-negative-number-constrained-types`](typing-customization.md#use-non-positive-negative-number-constrained-types)
- [`--use-object-type`](typing-customization.md#use-object-type)
- [`--use-one-literal-as-default`](model-customization.md#use-one-literal-as-default)
- [`--use-operation-id-as-name`](openapi-only-options.md#use-operation-id-as-name)
- [`--use-pendulum`](typing-customization.md#use-pendulum)
- [`--use-root-model-sequence-interface`](model-customization.md#use-root-model-sequence-interface)
- [`--use-root-model-type-alias`](typing-customization.md#use-root-model-type-alias)
- [`--use-schema-description`](field-customization.md#use-schema-description)
- [`--use-serialization-alias`](field-customization.md#use-serialization-alias)
- [`--use-serialize-as-any`](model-customization.md#use-serialize-as-any)
- [`--use-single-line-docstring`](field-customization.md#use-single-line-docstring)
- [`--use-specialized-enum`](typing-customization.md#use-specialized-enum)
- [`--use-standard-collections`](typing-customization.md#use-standard-collections)
- [`--use-standard-primitive-types`](typing-customization.md#use-standard-primitive-types)
- [`--use-status-code-in-response-name`](openapi-only-options.md#use-status-code-in-response-name)
- [`--use-subclass-enum`](model-customization.md#use-subclass-enum)
- [`--use-title-as-name`](field-customization.md#use-title-as-name)
- [`--use-total-false-for-typed-dict`](typing-customization.md#use-total-false-for-typed-dict)
- [`--use-tuple-for-fixed-items`](typing-customization.md#use-tuple-for-fixed-items)
- [`--use-tuple-for-fixed-length-arrays`](typing-customization.md#use-tuple-for-fixed-length-arrays)
- [`--use-type-alias`](typing-customization.md#use-type-alias)
- [`--use-type-alias-type`](typing-customization.md#use-type-alias-type)
- [`--use-type-checking-imports`](template-customization.md#use-type-checking-imports)
- [`--use-typed-nullable-map-values`](typing-customization.md#use-typed-nullable-map-values)
- [`--use-union-operator`](typing-customization.md#use-union-operator)
- [`--use-unique-items-as-set`](typing-customization.md#use-unique-items-as-set)

### V {#v}

- [`--validation`](openapi-only-options.md#validation)
- [`--validators`](template-customization.md#validators)
- [`--version`](utility-options.md#version)

### W {#w}

- [`--watch`](general-options.md#watch)
- [`--watch-delay`](general-options.md#watch-delay)
- [`--wrap-string-literal`](template-customization.md#wrap-string-literal)

---

# Base Options

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/base-options/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--emit-model-metadata`](#emit-model-metadata) | Write a separate JSON map from source schema references to t... |
| [`--encoding`](#encoding) | Specify character encoding for input and output files. |
| [`--external-ref-mapping`](#external-ref-mapping) | Map external `$ref` files to Python packages. |
| [`--http-backend`](#http-backend) | Select the HTTP client backend for remote schemas. |
| [`--input`](#input) | Specify the input schema file path. |
| [`--input-file-type`](#input-file-type) | Specify the input file type for code generation. |
| [`--input-model`](#input-model) | Import a Python type or dict schema from a module or Python ... |
| [`--input-model-ref-strategy`](#input-model-ref-strategy) | Strategy for referenced types when using --input-model. |
| [`--output`](#output) | Specify the destination path for generated Python code. |
| [`--preset`](#preset) | Apply an immutable built-in option preset. |
| [`--schema-version`](#schema-version) | Schema version to use for parsing. |
| [`--schema-version-mode`](#schema-version-mode) | Schema version validation mode. |
| [`--url`](#url) | Fetch a schema from a URL with custom HTTP headers. |

---

## 🍳 Recipes

### Generate a local schema file

Pin the input type and destination when the source extension is ambiguous or generated output needs a stable path.

**Options:** [`--input`](#input), [`--input-file-type`](#input-file-type), [`--output`](#output)

### Fetch a protected remote schema

Use URL input together with HTTP request controls for schemas served behind headers or slower endpoints.

**Options:** [`--url`](#url), [`--http-headers`](general-options.md#http-headers), [`--http-timeout`](general-options.md#http-timeout)

---

## `--emit-model-metadata` {#emit-model-metadata}

Write a separate JSON map from source schema references to the final generated models, modules, fields, and type hints.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input model_metadata.json --emit-model-metadata model-map.json --module-split-mode single --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--emit-model-metadata` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Root title",
      "type": "object",
      "properties": {
        "method": {
          "const": "thread/started"
        },
        "payload": {
          "$ref": "#/$defs/MetadataPayload"
        }
      },
      "required": ["method", "payload"],
      "$defs": {
        "MetadataPayload": {
          "title": "Payload title",
          "type": "object",
          "properties": {
            "id": {
              "type": "integer"
            }
          },
          "required": ["id"]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  model_metadata.json

    from __future__ import annotations

    from typing import Literal

    from pydantic import BaseModel

    from . import metadata_payload


    class RootTitle(BaseModel):
        method: Literal['thread/started']
        payload: metadata_payload.MetadataPayload
    ```

    <!-- fmt: on -->

    **Generated metadata (`model-map.json`):**

    <!-- fmt: off -->

    ```json
    {
      "version": 1,
      "models": [
        {
          "class_name": "RootTitle",
          "name": "RootTitle",
          "module": "root_title",
          "source_ref": "model_metadata.json#",
          "source_path": [],
          "title": "Root title",
          "fields": [
            {
              "name": "method",
              "alias": "method",
              "original_name": "method",
              "type": "Literal['thread/started']",
              "required": true
            },
            {
              "name": "payload",
              "alias": "payload",
              "original_name": "payload",
              "type": "metadata_payload.MetadataPayload",
              "required": true
            }
          ]
        },
        {
          "class_name": "MetadataPayload",
          "name": "MetadataPayload",
          "module": "metadata_payload",
          "source_ref": "model_metadata.json#/$defs/MetadataPayload",
          "source_path": [
            "$defs",
            "MetadataPayload"
          ],
          "title": "Payload title",
          "fields": [
            {
              "name": "id",
              "alias": "id",
              "original_name": "id",
              "type": "int",
              "required": true
            }
          ]
        }
      ]
    }
    ```

    <!-- fmt: on -->

---

## `--encoding` {#encoding}

Specify character encoding for input and output files.

The `--encoding` flag sets the character encoding used when reading
the schema file and writing the generated Python code. This is useful
for schemas containing non-ASCII characters (e.g., Japanese, Chinese).
Default is UTF-8, which is the standard encoding for JSON and most modern text files.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input encoding_test.json --encoding utf-8 # (1)!
    ```

    1. :material-arrow-left: `--encoding` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "日本語Model",
      "description": "モデルの説明文",
      "type": "object",
      "properties": {
        "名前": {
          "type": "string",
          "description": "ユーザー名"
        },
        "年齢": {
          "type": "integer"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  encoding_test.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field


    class 日本語Model(BaseModel):
        名前: str | None = Field(None, description='ユーザー名')
        年齢: int | None = None
    ```

    <!-- fmt: on -->

---

## `--external-ref-mapping` {#external-ref-mapping}

Map external `$ref` files to Python packages.

Use `--external-ref-mapping FILE_PATH=PYTHON_PACKAGE` to import referenced models from an existing package,
instead of generating duplicate classes from external schema files.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --input-file-type openapi --external-ref-mapping common.yaml=mypackage.shared.models # (1)!
    ```

    1. :material-arrow-left: `--external-ref-mapping` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.3"
    info:
      title: API
      version: "1.0.0"
    paths: {}
    components:
      schemas:
        UserResponse:
          type: object
          properties:
            user:
              $ref: "common.yaml#/components/schemas/User"
            request_id:
              type: string
          required:
            - user
            - request_id
        ErrorResponse:
          type: object
          properties:
            error:
              $ref: "common.yaml#/components/schemas/Error"
            timestamp:
              type: string
              format: date-time
          required:
            - error
            - timestamp
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from mypackage.shared.models import Error, User
    from pydantic import AwareDatetime, BaseModel


    class UserResponse(BaseModel):
        user: User
        request_id: str


    class ErrorResponse(BaseModel):
        error: Error
        timestamp: AwareDatetime
    ```

    <!-- fmt: on -->

---

## `--http-backend` {#http-backend}

Select the HTTP client backend for remote schemas.

`--http-backend auto` selects stable HTTPX when its client module is installed
and selects experimental HTTPX2 only when that module is absent. Explicit
`httpx` or `httpx2` selections require that exact backend. Explicit selections
and paired dependency errors do not fall back.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pet_simple.json --http-backend auto # (1)!
    ```

    1. :material-arrow-left: `--http-backend` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  http://localhost/schema.json

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--input` {#input}

Specify the input schema file path.

The `--input` flag specifies the path to the schema file (JSON Schema,
OpenAPI, GraphQL, etc.). Multiple input files can be specified to merge
schemas. Required unless using `--url` to fetch schema from a URL.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pet_simple.json --output output.py # (1)!
    ```

    1. :material-arrow-left: `--input` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  pet_simple.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--input-file-type` {#input-file-type}

Specify the input file type for code generation.

The `--input-file-type` flag explicitly sets the input format.

**Important distinction:**

- Use `jsonschema`, `openapi`, `asyncapi`, `graphql`, `mcp-tools`, `xmlschema`,
  `protobuf`, or `avro` for **schema definition files**
- Use `json`, `yaml`, or `csv` for **raw sample data** to automatically infer a schema

For example, if you have a JSON Schema written in YAML format, use `--input-file-type jsonschema`,
not `--input-file-type yaml`. The `yaml` type treats the file as raw data and infers a schema from it.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pet.json --input-file-type json # (1)!
    ```

    1. :material-arrow-left: `--input-file-type` - the option documented here

??? example "Examples"

    === "JSON"

        **Input Schema:**

        ```json
        {
          "Pet": {
            "name": "dog",
            "age": 2
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  pet.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Pet(BaseModel):
            name: str
            age: int


        class Model(BaseModel):
            Pet_1: Pet = Field(..., alias='Pet')
        ```

        <!-- fmt: on -->

    === "YAML"

        **Input Schema:**

        ```yaml
        Pet:
          name: cat
          age: 3
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  pet.yaml
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Pet(BaseModel):
            name: str
            age: int


        class Model(BaseModel):
            Pet_1: Pet = Field(..., alias='Pet')
        ```

        <!-- fmt: on -->

---

## `--input-model` {#input-model}

Import a Python type or dict schema from a module or Python file.

Use the format `module:Object` or `path/to/file.py:Object` to specify the type.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --input-model mymodule:MyModel # (1)!
    ```

    1. :material-arrow-left: `--input-model` - the option documented here

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: cli-reference.base-options.input-model.example -->
??? example "Examples"

    **Command:**
    <!-- fmt: off -->

    ```bash
    datamodel-codegen \
      --input-model tests.data.python.input_model.typeddict_models:User \
      --output model.py
    ```

    <!-- fmt: on -->

    **Input Model (`tests/data/python/input_model/typeddict_models.py`):**
    <!-- fmt: off -->

    ```python
    """TypedDict models for --input-model tests."""

    from typing_extensions import TypedDict


    class User(TypedDict):
        """User TypedDict with basic fields."""

        name: str
        age: int
    ```

    <!-- fmt: on -->

    **Output:**
    <!-- fmt: off -->

    ```python
    from __future__ import annotations

    from pydantic import BaseModel, Field


    class User(BaseModel):
        name: str = Field(..., title='Name')
        age: int = Field(..., title='Age')
    ```

    <!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: cli-reference.base-options.input-model.example -->

---

## `--input-model-ref-strategy` {#input-model-ref-strategy}

Strategy for referenced types when using --input-model.

The `--input-model-ref-strategy` option determines whether to regenerate or import
referenced types. Use `regenerate-all` (default) to regenerate all types,
`reuse-foreign` to import types from different families (like enums when generating
dataclasses) while regenerating same-family types, or `reuse-all` to import all
referenced types directly.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --input-model-ref-strategy reuse-foreign # (1)!
    ```

    1. :material-arrow-left: `--input-model-ref-strategy` - the option documented here

??? example "Examples"

    **Output:**

---

## `--output` {#output}

Specify the destination path for generated Python code.

The `--output` flag specifies where to write the generated Python code.
It can be either a file path (single-file output) or a directory path
(multi-file output for modular schemas). If omitted, the generated code
is written to stdout.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pet_simple.json --output output.py # (1)!
    ```

    1. :material-arrow-left: `--output` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  pet_simple.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--preset` {#preset}

Apply an immutable built-in option preset.

The `standard-py312-20260619` preset enables the recommended modern Python output style for
new projects. The preset name pins generated Python syntax and backports.

**Related:** [`--target-python-version`](model-customization.md#target-python-version)

**See also:** [pyproject.toml Configuration](../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --preset standard-py312-20260619 # (1)!
    ```

    1. :material-arrow-left: `--preset` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": ["string", "null"],
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  person.json

    from __future__ import annotations

    from typing import Annotated, Any

    from pydantic import BaseModel, ConfigDict, Field


    class Person(BaseModel):
        model_config = ConfigDict(
            populate_by_name=True,
        )
        first_name: Annotated[
            str | None, Field(alias='firstName', description="The person's first name.")
        ] = None
        last_name: Annotated[
            str | None, Field(alias='lastName', description="The person's last name.")
        ] = None
        age: Annotated[
            int | None,
            Field(
                description='Age in years which must be equal to or greater than zero.',
                ge=0,
            ),
        ] = None
        friends: list[Any] | None = None
        comment: Annotated[None, Field(None)] = None
    ```

    <!-- fmt: on -->

---

## `--schema-version` {#schema-version}

Schema version to use for parsing.

The `--schema-version` option specifies the schema version to use instead of auto-detection.
Valid values depend on input type: JsonSchema (draft-04, draft-06, draft-07, 2019-09, 2020-12)
or OpenAPI (3.0, 3.1, 3.2). Default is 'auto' (detected from $schema or openapi field).

!!! tip "Usage"

    ```bash
    datamodel-codegen --input simple_string.json --schema-version draft-07 # (1)!
    ```

    1. :material-arrow-left: `--schema-version` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: "3.0.0"
        info:
          version: 1.0.0
          title: Swagger Petstore
          license:
            name: MIT
        servers:
          - url: http://petstore.swagger.io/v1
        paths:
          /pets:
            get:
              summary: List all pets
              operationId: listPets
              tags:
                - pets
              parameters:
                - name: limit
                  in: query
                  description: How many items to return at one time (max 100)
                  required: false
                  schema:
                    type: integer
                    format: int32
              responses:
                '200':
                  description: A paged array of pets
                  headers:
                    x-next:
                      description: A link to the next page of responses
                      schema:
                        type: string
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
            post:
              summary: Create a pet
              operationId: createPets
              tags:
                - pets
              responses:
                '201':
                  description: Null response
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
          /pets/{petId}:
            get:
              summary: Info for a specific pet
              operationId: showPetById
              tags:
                - pets
              parameters:
                - name: petId
                  in: path
                  required: true
                  description: The id of the pet to retrieve
                  schema:
                    type: string
              responses:
                '200':
                  description: Expected response to a valid request
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
            x-amazon-apigateway-integration:
              uri:
                Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
              passthroughBehavior: when_no_templates
              httpMethod: POST
              type: aws_proxy
        components:
          schemas:
            Pet:
              required:
                - id
                - name
              properties:
                id:
                  type: integer
                  format: int64
                  default: 1
                name:
                  type: string
                tag:
                  type: string
            Pets:
              type: array
              items:
                $ref: "#/components/schemas/Pet"
            Users:
              type: array
              items:
                required:
                  - id
                  - name
                properties:
                  id:
                    type: integer
                    format: int64
                  name:
                    type: string
                  tag:
                    type: string
            Id:
              type: string
            Rules:
              type: array
              items:
                type: string
            Error:
              description: error result
              required:
                - code
                - message
              properties:
                code:
                  type: integer
                  format: int32
                message:
                  type: string
            apis:
              type: array
              items:
                type: object
                properties:
                  apiKey:
                    type: string
                    description: To be used as a dataset parameter value
                  apiVersionNumber:
                    type: string
                    description: To be used as a version parameter value
                  apiUrl:
                    type: string
                    format: uri
                    description: "The URL describing the dataset's fields"
                  apiDocumentationUrl:
                    type: string
                    format: uri
                    description: A URL to the API console for each API
            Event:
              type: object
              description: Event object
              properties:
                name:
                  type: string
            Result:
                type: object
                properties:
                  event:
                    $ref: '#/components/schemas/Event'
        ```

        **Output:**

        > **Error:** File not found: openapi/api.py

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema",
          "type": "object",
          "properties": {"s": {"type": ["string"]}},
          "required": ["s"]
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  simple_string.json

        from __future__ import annotations

        from pydantic import BaseModel


        class Model(BaseModel):
            s: str
        ```

        <!-- fmt: on -->

---

## `--schema-version-mode` {#schema-version-mode}

Schema version validation mode.

The `--schema-version-mode` option controls how schema version validation is performed.
'lenient' (default): accept all features regardless of version.
'strict': warn on features outside the declared/detected version.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input simple_string.json --schema-version-mode lenient # (1)!
    ```

    1. :material-arrow-left: `--schema-version-mode` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema",
      "type": "object",
      "properties": {"s": {"type": ["string"]}},
      "required": ["s"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  simple_string.json

    from __future__ import annotations

    from pydantic import BaseModel


    class Model(BaseModel):
        s: str
    ```

    <!-- fmt: on -->

---

## `--url` {#url}

Fetch a schema from a URL with custom HTTP headers.

The `--url` flag specifies a remote URL to fetch the schema from instead of
a local file. The `--http-headers` flag adds request headers in
`HeaderName:HeaderValue` format.

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --http-headers "Authorization:Bearer token" # (1)!
    ```

    1. :material-arrow-left: `--url` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

---

# Model Customization

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/model-customization/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--alias-generator`](#alias-generator) | Use a Pydantic v2 alias generator in model_config. |
| [`--allow-extra-fields`](#allow-extra-fields) | Allow extra fields in generated Pydantic models (extra='allo... |
| [`--allow-leading-underscore-class-name`](#allow-leading-underscore-class-name) | Allow an explicitly specified root class name to start with ... |
| [`--allow-population-by-field-name`](#allow-population-by-field-name) | Allow Pydantic model population by field name (not just alia... |
| [`--base-class`](#base-class) | Specify a custom base class for generated models. |
| [`--base-class-map`](#base-class-map) | Specify different base classes for specific models via JSON ... |
| [`--class-name`](#class-name) | Override the auto-generated class name with a custom name. |
| [`--class-name-affix-scope`](#class-name-affix-scope) | Control which classes receive the prefix/suffix. |
| [`--class-name-prefix`](#class-name-prefix) | Add a prefix to all generated class names. |
| [`--class-name-suffix`](#class-name-suffix) | Add a suffix to all generated class names. |
| [`--collapse-reuse-models`](#collapse-reuse-models) | Collapse duplicate models by replacing references instead of... |
| [`--collapse-root-models`](#collapse-root-models) | Inline root model definitions instead of creating separate w... |
| [`--collapse-root-models-name-strategy`](#collapse-root-models-name-strategy) | Select which name to keep when collapsing root models with o... |
| [`--dataclass-arguments`](#dataclass-arguments) | Customize dataclass decorator arguments via JSON dictionary. |
| [`--duplicate-name-suffix`](#duplicate-name-suffix) | Customize suffix for duplicate model names. |
| [`--enable-faux-immutability`](#enable-faux-immutability) | Enable faux immutability in Pydantic models (frozen=True). |
| [`--force-optional`](#force-optional) | Force all fields to be Optional regardless of required statu... |
| [`--frozen-dataclasses`](#frozen-dataclasses) | Generate frozen dataclasses with optional keyword-only field... |
| [`--keep-model-order`](#keep-model-order) | Keep generated model order deterministic while respecting de... |
| [`--keyword-only`](#keyword-only) | Generate dataclasses with keyword-only fields (Python 3.10+)... |
| [`--model-extra-keys`](#model-extra-keys) | Add model-level schema extensions to ConfigDict json_schema_... |
| [`--model-extra-keys-without-x-prefix`](#model-extra-keys-without-x-prefix) | Strip x- prefix from model-level schema extensions and add t... |
| [`--model-name-map`](#model-name-map) | Rename generated model classes from a JSON mapping. |
| [`--naming-strategy`](#naming-strategy) | Use parent-prefixed naming strategy for duplicate model name... |
| [`--output-model-type`](#output-model-type) | Select the output model type (Pydantic v2, Pydantic v2 datac... |
| [`--parent-scoped-naming`](#parent-scoped-naming) | Namespace models by their parent scope to avoid naming confl... |
| [`--reuse-model`](#reuse-model) | Reuse identical model definitions instead of generating dupl... |
| [`--reuse-scope`](#reuse-scope) | Scope for model reuse detection (root or tree). |
| [`--skip-root-model`](#skip-root-model) | Skip generation of root model when schema contains nested de... |
| [`--strict-nullable`](#strict-nullable) | Treat default field as a non-nullable field. |
| [`--strip-default-none`](#strip-default-none) | Remove fields with None as default value from generated mode... |
| [`--target-pydantic-version`](#target-pydantic-version) | Target Pydantic version for generated code compatibility. |
| [`--target-python-version`](#target-python-version) | Target Python version for generated code syntax and imports. |
| [`--union-mode`](#union-mode) | Union mode for combining anyOf/oneOf schemas (smart or left_... |
| [`--use-default`](#use-default) | Use default values from schema in generated models. |
| [`--use-default-factory-for-optional-nested-models`](#use-default-factory-for-optional-nested-models) | Generate default_factory for optional nested model fields. |
| [`--use-default-kwarg`](#use-default-kwarg) | Use default= keyword argument instead of positional argument... |
| [`--use-frozen-field`](#use-frozen-field) | Generate frozen (immutable) field definitions for readOnly p... |
| [`--use-generic-base-class`](#use-generic-base-class) | Generate a shared base class with model configuration to avo... |
| [`--use-missing-sentinel`](#use-missing-sentinel) | Use Pydantic's MISSING sentinel for unset optional BaseModel... |
| [`--use-msgspec-nullable-enum-alias`](#use-msgspec-nullable-enum-alias) | Write a msgspec.Struct enum that lists null as an Enum and a... |
| [`--use-msgspec-tagged-unions`](#use-msgspec-tagged-unions) | Write a msgspec.Struct discriminated union as tagged structs... |
| [`--use-one-literal-as-default`](#use-one-literal-as-default) | Use single literal value as default when enum has only one o... |
| [`--use-root-model-sequence-interface`](#use-root-model-sequence-interface) | Make non-null sequence-like Pydantic v2 RootModel classes im... |
| [`--use-serialize-as-any`](#use-serialize-as-any) | Wrap fields with subtypes in Pydantic's SerializeAsAny. |
| [`--use-subclass-enum`](#use-subclass-enum) | Generate typed Enum subclasses for enums with specific field... |

---

## 🍳 Recipes

### Target Pydantic v2 on modern Python

Set the output model family and Python/Pydantic compatibility targets together.

**Options:** [`--output-model-type`](#output-model-type), [`--target-python-version`](#target-python-version), [`--target-pydantic-version`](#target-pydantic-version)

### Deduplicate reusable schemas

Reuse equivalent models and tune the scope or root-model behavior when schemas repeat.

**Options:** [`--reuse-model`](#reuse-model), [`--reuse-scope`](#reuse-scope), [`--collapse-root-models`](#collapse-root-models)

---

## `--alias-generator` {#alias-generator}

Use a Pydantic v2 alias generator in model_config.

The `--alias-generator` option emits a per-model ConfigDict alias generator for
Pydantic v2 BaseModel output and omits matching per-field aliases. With
`--target-pydantic-version 2` every field alias is written out, so aliases do not
depend on the generator of the installed Pydantic.

**Related:** [`--output-model-type`](#output-model-type), [`--snake-case-field`](field-customization.md#snake-case-field)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input alias_generator.json --snake-case-field --alias-generator to_camel --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--alias-generator` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "AliasGeneratorModel",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "foo_bar": {
          "type": "string"
        },
        "weird-url": {
          "type": "integer"
        }
      },
      "required": ["firstName", "foo_bar", "weird-url"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  alias_generator.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, ConfigDict, Field
    from pydantic.alias_generators import to_camel


    class AliasGeneratorModel(BaseModel):
        model_config = ConfigDict(
            populate_by_name=True,
            alias_generator=to_camel,
        )
        first_name: str
        last_name: str | None = None
        foo_bar: str = Field(..., alias='foo_bar')
        weird_url: int = Field(..., alias='weird-url')
    ```

    <!-- fmt: on -->

---

## `--allow-extra-fields` {#allow-extra-fields}

Allow extra fields in generated Pydantic models (extra='allow').

The `--allow-extra-fields` flag configures the code generation behavior.

**Deprecated:** --allow-extra-fields is deprecated. Use --extra-fields=allow instead.

**Option relationships:**

- **Implies:** [`--extra-fields`](field-customization.md#extra-fields) = `allow`

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --allow-extra-fields # (1)!
    ```

    1. :material-arrow-left: `--allow-extra-fields` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  api.yaml
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel


        class Pet(BaseModel):
            model_config = ConfigDict(
                extra='allow',
            )
            id: int
            name: str
            tag: str | None = None


        class Pets(RootModel[list[Pet]]):
            root: list[Pet]


        class User(BaseModel):
            model_config = ConfigDict(
                extra='allow',
            )
            id: int
            name: str
            tag: str | None = None


        class Users(RootModel[list[User]]):
            root: list[User]


        class Id(RootModel[str]):
            root: str


        class Rules(RootModel[list[str]]):
            root: list[str]


        class Error(BaseModel):
            model_config = ConfigDict(
                extra='allow',
            )
            code: int
            message: str


        class Api(BaseModel):
            model_config = ConfigDict(
                extra='allow',
            )
            apiKey: str | None = Field(
                None, description='To be used as a dataset parameter value'
            )
            apiVersionNumber: str | None = Field(
                None, description='To be used as a version parameter value'
            )
            apiUrl: AnyUrl | None = Field(
                None, description="The URL describing the dataset's fields"
            )
            apiDocumentationUrl: AnyUrl | None = Field(
                None, description='A URL to the API console for each API'
            )


        class Apis(RootModel[list[Api]]):
            root: list[Api]


        class Event(BaseModel):
            model_config = ConfigDict(
                extra='allow',
            )
            name: str | None = None


        class Result(BaseModel):
            model_config = ConfigDict(
                extra='allow',
            )
            event: Event | None = None
        ```

        <!-- fmt: on -->

---

## `--allow-leading-underscore-class-name` {#allow-leading-underscore-class-name}

Allow an explicitly specified root class name to start with an underscore.

By default, leading underscores in class names are normalized to avoid private
model names. Use --allow-leading-underscore-class-name together with an explicit
--class-name when you need the generated root model to preserve that name
exactly.

**Related:** [`--class-name`](#class-name)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input class_name_affix.json --class-name __ParsedModel --allow-leading-underscore-class-name --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--allow-leading-underscore-class-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "type": "object",
      "properties": {
        "status": {
          "$ref": "#/$defs/Status"
        },
        "item": {
          "$ref": "#/$defs/Item"
        }
      },
      "$defs": {
        "Status": {
          "type": "string",
          "enum": ["active", "inactive"]
        },
        "Item": {
          "type": "object",
          "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"}
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  class_name_affix.json

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel


    class Status(Enum):
        active = 'active'
        inactive = 'inactive'


    class Item(BaseModel):
        id: int | None = None
        name: str | None = None


    class __ParsedModel(BaseModel):
        status: Status | None = None
        item: Item | None = None
    ```

    <!-- fmt: on -->

---

## `--allow-population-by-field-name` {#allow-population-by-field-name}

Allow Pydantic model population by field name (not just alias).

The `--allow-population-by-field-name` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --allow-population-by-field-name # (1)!
    ```

    1. :material-arrow-left: `--allow-population-by-field-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  api.yaml
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel


        class Pet(BaseModel):
            model_config = ConfigDict(
                populate_by_name=True,
            )
            id: int
            name: str
            tag: str | None = None


        class Pets(RootModel[list[Pet]]):
            root: list[Pet]


        class User(BaseModel):
            model_config = ConfigDict(
                populate_by_name=True,
            )
            id: int
            name: str
            tag: str | None = None


        class Users(RootModel[list[User]]):
            root: list[User]


        class Id(RootModel[str]):
            root: str


        class Rules(RootModel[list[str]]):
            root: list[str]


        class Error(BaseModel):
            model_config = ConfigDict(
                populate_by_name=True,
            )
            code: int
            message: str


        class Api(BaseModel):
            model_config = ConfigDict(
                populate_by_name=True,
            )
            apiKey: str | None = Field(
                None, description='To be used as a dataset parameter value'
            )
            apiVersionNumber: str | None = Field(
                None, description='To be used as a version parameter value'
            )
            apiUrl: AnyUrl | None = Field(
                None, description="The URL describing the dataset's fields"
            )
            apiDocumentationUrl: AnyUrl | None = Field(
                None, description='A URL to the API console for each API'
            )


        class Apis(RootModel[list[Api]]):
            root: list[Api]


        class Event(BaseModel):
            model_config = ConfigDict(
                populate_by_name=True,
            )
            name: str | None = None


        class Result(BaseModel):
            model_config = ConfigDict(
                populate_by_name=True,
            )
            event: Event | None = None
        ```

        <!-- fmt: on -->

---

## `--base-class` {#base-class}

Specify a custom base class for generated models.

The `--base-class` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --base-class custom_module.Base # (1)!
    ```

    1. :material-arrow-left: `--base-class` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, Field, RootModel

    from custom_module import Base


    class Pet(Base):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(Base):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(Base):
        code: int
        message: str


    class Api(Base):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(Base):
        name: str | None = None


    class Result(Base):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--base-class-map` {#base-class-map}

Specify different base classes for specific models via JSON mapping.

The `--base-class-map` option allows you to assign different base classes
to specific models. This is useful when you want selective base class inheritance,
for example, applying custom base classes only to specific models while leaving
others with the default `BaseModel`.

Priority: `--base-class-map` > `customBasePath` (schema extension) > `--base-class`

You can specify either a single base class as a string, or multiple base classes
(mixins) as a list:

- Single: `{"Person": "custom.bases.PersonBase"}`
- Multiple: `{"User": ["mixins.AuditMixin", "mixins.TimestampMixin"]}`

You can pass the mapping either inline as JSON or as a path to a JSON file.

When using multiple base classes, the specified classes are used directly without
adding `BaseModel`. Ensure your mixins inherit from `BaseModel` if needed.

**Related:** [`--base-class`](#base-class)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input base_class_map.json --base-class-map '{"Person": "custom.bases.PersonBase", "Animal": "custom.bases.AnimalBase"}' # (1)!
    ```

    1. :material-arrow-left: `--base-class-map` - the option documented here

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: cli-reference.model-customization.base-class-map.example -->
??? example "Examples"

    **Input Schema:**
    <!-- fmt: off -->

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "Person": {
          "type": "object",
          "properties": {
            "name": {"type": "string"}
          }
        },
        "Animal": {
          "type": "object",
          "properties": {
            "species": {"type": "string"}
          }
        },
        "Car": {
          "type": "object",
          "properties": {
            "model": {"type": "string"}
          }
        }
      }
    }
    ```

    <!-- fmt: on -->

    **Output:**
    <!-- fmt: off -->

    ```python
    from __future__ import annotations

    from typing import Any

    from custom.bases import AnimalBase, PersonBase
    from pydantic import BaseModel, RootModel


    class Model(RootModel[Any]):
        root: Any


    class Person(PersonBase):
        name: str | None = None


    class Animal(AnimalBase):
        species: str | None = None


    class Car(BaseModel):
        model: str | None = None
    ```

    <!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: cli-reference.model-customization.base-class-map.example -->

---

## `--class-name` {#class-name}

Override the auto-generated class name with a custom name.

The --class-name option allows you to specify a custom class name for the
generated model. This is useful when the schema title is invalid as a Python
class name (e.g., starts with a number) or when you want to use a different
naming convention than what's in the schema.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input invalid_model_name.json --class-name ValidModelName # (1)!
    ```

    1. :material-arrow-left: `--class-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "1 xyz",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": "string",
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  invalid_model_name.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, Field, conint


    class ValidModelName(BaseModel):
        firstName: str | None = Field(None, description="The person's first name.")
        lastName: str | None = Field(None, description="The person's last name.")
        age: conint(ge=0) | None = Field(
            None, description='Age in years which must be equal to or greater than zero.'
        )
        friends: list[Any] | None = None
        comment: None = Field(None)
    ```

    <!-- fmt: on -->

---

## `--class-name-affix-scope` {#class-name-affix-scope}

Control which classes receive the prefix/suffix.

The --class-name-affix-scope option controls which types of classes receive the
prefix or suffix specified by --class-name-prefix or --class-name-suffix:
- 'all': Apply to all classes (models and enums) - this is the default
- 'models': Apply only to model classes (BaseModel, dataclass, TypedDict, etc.)
- 'enums': Apply only to enum classes

**Related:** [`--class-name-prefix`](#class-name-prefix), [`--class-name-suffix`](#class-name-suffix)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input class_name_affix.json --class-name-suffix Schema --class-name-affix-scope models # (1)!
    ```

    1. :material-arrow-left: `--class-name-affix-scope` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "type": "object",
      "properties": {
        "status": {
          "$ref": "#/$defs/Status"
        },
        "item": {
          "$ref": "#/$defs/Item"
        }
      },
      "$defs": {
        "Status": {
          "type": "string",
          "enum": ["active", "inactive"]
        },
        "Item": {
          "type": "object",
          "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"}
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  class_name_affix.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel


    class Status(Enum):
        active = 'active'
        inactive = 'inactive'


    class ItemSchema(BaseModel):
        id: int | None = None
        name: str | None = None


    class ModelSchemaSchema(BaseModel):
        status: Status | None = None
        item: ItemSchema | None = None
    ```

    <!-- fmt: on -->

---

## `--class-name-prefix` {#class-name-prefix}

Add a prefix to all generated class names.

The --class-name-prefix option allows you to add a prefix to all generated class
names, including both models and enums. This is useful for namespacing generated
code or avoiding conflicts with existing classes.

**Related:** [`--class-name-affix-scope`](#class-name-affix-scope), [`--class-name-suffix`](#class-name-suffix)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input class_name_affix.json --class-name-prefix Api # (1)!
    ```

    1. :material-arrow-left: `--class-name-prefix` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "type": "object",
      "properties": {
        "status": {
          "$ref": "#/$defs/Status"
        },
        "item": {
          "$ref": "#/$defs/Item"
        }
      },
      "$defs": {
        "Status": {
          "type": "string",
          "enum": ["active", "inactive"]
        },
        "Item": {
          "type": "object",
          "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"}
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  class_name_affix.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel


    class ApiStatus(Enum):
        active = 'active'
        inactive = 'inactive'


    class ApiItem(BaseModel):
        id: int | None = None
        name: str | None = None


    class ApiModel(BaseModel):
        status: ApiStatus | None = None
        item: ApiItem | None = None
    ```

    <!-- fmt: on -->

---

## `--class-name-suffix` {#class-name-suffix}

Add a suffix to all generated class names.

The --class-name-suffix option allows you to add a suffix to all generated class
names, including both models and enums. This is useful for distinguishing generated
classes (e.g., adding 'Schema' or 'Model' suffix).

**Related:** [`--class-name-affix-scope`](#class-name-affix-scope), [`--class-name-prefix`](#class-name-prefix)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input class_name_affix.json --class-name-suffix Schema # (1)!
    ```

    1. :material-arrow-left: `--class-name-suffix` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "type": "object",
      "properties": {
        "status": {
          "$ref": "#/$defs/Status"
        },
        "item": {
          "$ref": "#/$defs/Item"
        }
      },
      "$defs": {
        "Status": {
          "type": "string",
          "enum": ["active", "inactive"]
        },
        "Item": {
          "type": "object",
          "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"}
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  class_name_affix.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel


    class StatusSchema(Enum):
        active = 'active'
        inactive = 'inactive'


    class ItemSchema(BaseModel):
        id: int | None = None
        name: str | None = None


    class ModelSchema(BaseModel):
        status: StatusSchema | None = None
        item: ItemSchema | None = None
    ```

    <!-- fmt: on -->

---

## `--collapse-reuse-models` {#collapse-reuse-models}

Collapse duplicate models by replacing references instead of inheritance.

The `--collapse-reuse-models` flag, when used with `--reuse-model`,
eliminates redundant empty subclasses (e.g., `class Foo(Bar): pass`)
by replacing all references to duplicate models with the canonical model.

**Related:** [`--reuse-model`](#reuse-model)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input duplicate_models.json --reuse-model --collapse-reuse-models # (1)!
    ```

    1. :material-arrow-left: `--collapse-reuse-models` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
        "Arm Right": {
            "Joint 1": 5,
            "Joint 2": 3,
            "Joint 3": 66
        },
        "Arm Left": {
            "Joint 1": 55,
            "Joint 2": 13,
            "Joint 3": 6
        },
        "Head": {
            "Joint 1": 10
        }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  duplicate_models.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field


    class ArmRight(BaseModel):
        Joint_1: int = Field(..., alias='Joint 1')
        Joint_2: int = Field(..., alias='Joint 2')
        Joint_3: int = Field(..., alias='Joint 3')


    class Head(BaseModel):
        Joint_1: int = Field(..., alias='Joint 1')


    class Model(BaseModel):
        Arm_Right: ArmRight = Field(..., alias='Arm Right')
        Arm_Left: ArmRight = Field(..., alias='Arm Left')
        Head_1: Head = Field(..., alias='Head')
    ```

    <!-- fmt: on -->

---

## `--collapse-root-models` {#collapse-root-models}

Inline root model definitions instead of creating separate wrapper classes.

The `--collapse-root-models` option generates simpler output by inlining root models
directly instead of creating separate wrapper types. This shows how different output
model types (Pydantic v2, dataclass, TypedDict, msgspec) handle const fields.

**See also:** [Model Reuse and Deduplication](../model-reuse.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input const.yaml --collapse-root-models # (1)!
    ```

    1. :material-arrow-left: `--collapse-root-models` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: '3.0.2'
        components:
          schemas:
            ApiVersion:
              description: The version of this API
              type: string
              const: v1
            Api:
              type: object
              required:
                - version
              properties:
                version:
                  $ref: "#/components/schemas/ApiVersion"
        ```

        **Output:**

        === "Pydantic v2"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  const.yaml
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Literal

            from pydantic import BaseModel, Field


            class Api(BaseModel):
                version: Literal['v1'] = Field(..., description='The version of this API')
            ```

            <!-- fmt: on -->

        === "dataclass"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  const.yaml
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from dataclasses import dataclass
            from typing import Literal


            @dataclass
            class Api:
                version: Literal['v1']
            ```

            <!-- fmt: on -->

        === "TypedDict"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  const.yaml
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Literal, TypedDict


            class Api(TypedDict):
                version: Literal['v1']
            ```

            <!-- fmt: on -->

        === "msgspec"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  const.yaml
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Annotated, Literal

            from msgspec import Meta, Struct


            class Api(Struct):
                version: Annotated[Literal['v1'], Meta(description='The version of this API')]
            ```

            <!-- fmt: on -->

        === "Without Option (Baseline)"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  const.yaml
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from pydantic import BaseModel, Field


            class ApiVersion(BaseModel):
                __root__: str = Field('v1', const=True, description='The version of this API')


            class Api(BaseModel):
                version: ApiVersion
            ```

            <!-- fmt: on -->

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "type": "object",
          "properties": {
            "field": {
              "anyOf": [
                {"$ref": "#/$defs/NullType1"},
                {"$ref": "#/$defs/NullType2"}
              ]
            }
          },
          "$defs": {
            "NullType1": {
              "type": "null"
            },
            "NullType2": {
              "type": "null"
            }
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  collapse_root_models_empty_union.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Any

        from pydantic import BaseModel


        class Model(BaseModel):
            field: Any = None
        ```

        <!-- fmt: on -->

---

## `--collapse-root-models-name-strategy` {#collapse-root-models-name-strategy}

Select which name to keep when collapsing root models with object references.

The --collapse-root-models-name-strategy option controls naming when collapsing
root models. 'child' keeps the inner model's name, 'parent' uses the wrapper's name.

**Related:** [`--collapse-root-models`](#collapse-root-models)

**Option relationships:**

- **Requires:** [`--collapse-root-models`](model-customization.md#collapse-root-models) enabled - `--collapse-root-models-name-strategy` requires `--collapse-root-models`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input collapse_root_models_name_strategy_child.json --collapse-root-models --collapse-root-models-name-strategy child # (1)!
    ```

    1. :material-arrow-left: `--collapse-root-models-name-strategy` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "metadata": {
          "$ref": "#/$defs/ISectionBlockMetadata"
        }
      },
      "$defs": {
        "ISectionBlockMetadata": {
          "$ref": "#/$defs/FieldType2"
        },
        "FieldType2": {
          "type": "object",
          "properties": {
            "asText": {
              "type": "string"
            }
          },
          "required": ["asText"]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  collapse_root_models_name_strategy_child.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class FieldType2(BaseModel):
        asText: str


    class Model(BaseModel):
        metadata: FieldType2 | None = None
    ```

    <!-- fmt: on -->

---

## `--dataclass-arguments` {#dataclass-arguments}

Customize dataclass decorator arguments via JSON dictionary.

The `--dataclass-arguments` flag accepts custom dataclass arguments as a JSON
dictionary (e.g., '{"frozen": true, "kw_only": true, "slots": true, "order": true}').
This overrides individual flags like --frozen-dataclasses and provides fine-grained
control over dataclass generation.

**Related:** [`--frozen-dataclasses`](#frozen-dataclasses), [`--keyword-only`](#keyword-only)

**See also:** [Output Model Types](../output-model-types.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input simple-star-wars.graphql --output-model-type dataclasses.dataclass --dataclass-arguments '{"slots": true, "order": true}' # (1)!
    ```

    1. :material-arrow-left: `--dataclass-arguments` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    type Person {
        id: ID!
        name: String!
        height: Int
        mass: Int
        hair_color: String
        skin_color: String
        eye_color: String
        birth_year: String
        gender: String

        # Relationships
        homeworld_id: ID
        homeworld: Planet
        species: [Species!]!
        species_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
        starships: [Starship!]!
        starships_ids: [ID!]!
        vehicles: [Vehicle!]!
        vehicles_ids: [ID!]!
    }

    type Planet {
        id: ID!
        name: String!
        rotation_period: String
        orbital_period: String
        diameter: String
        climate: String
        gravity: String
        terrain: String
        surface_water: String
        population: String

        # Relationships
        residents: [Person!]!
        residents_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
    }

    type Species {
        id: ID!
        name: String!
        classification: String
        designation: String
        average_height: String
        skin_colors: String
        hair_colors: String
        eye_colors: String
        average_lifespan: String
        language: String

        # Relationships
        people: [Person!]!
        people_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
    }

    type Vehicle {
        id: ID!
        name: String!
        model: String
        manufacturer: String
        cost_in_credits: String
        length: String
        max_atmosphering_speed: String
        crew: String
        passengers: String
        cargo_capacity: String
        consumables: String
        vehicle_class: String

        # Relationships
        pilots: [Person!]!
        pilots_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
    }

    type Starship {
        id: ID!
        name: String!
        model: String
        manufacturer: String
        cost_in_credits: String
        length: String
        max_atmosphering_speed: String
        crew: String
        passengers: String
        cargo_capacity: String
        consumables: String
        hyperdrive_rating: String
        MGLT: String
        starship_class: String

        # Relationships
        pilots: [Person!]!
        pilots_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
    }

    type Film {
      id: ID!
      title: String!
      episode_id: Int!
      opening_crawl: String!
      director: String!
      producer: String
      release_date: String!

      # Relationships
      characters: [Person!]!
      characters_ids: [ID!]!
      planets: [Planet!]!
      planets_ids: [ID!]!
      starships: [Starship!]!
      starships_ids: [ID!]!
      vehicles: [Vehicle!]!
      vehicles_ids: [ID!]!
      species: [Species!]!
      species_ids: [ID!]!
    }

    type Query {
      planet(id: ID!): Planet
      listPlanets(page: Int): [Planet!]!
      person(id: ID!): Person
      listPeople(page: Int): [Person!]!
      species(id: ID!): Species
      listSpecies(page: Int): [Species!]!
      film(id: ID!): Film
      listFilms(page: Int): [Film!]!
      starship(id: ID!): Starship
      listStarships(page: Int): [Starship!]!
      vehicle(id: ID!): Vehicle
      listVehicles(page: Int): [Vehicle!]!
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  simple-star-wars.graphql
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from dataclasses import dataclass
    from typing import Literal, TypeAlias

    Boolean: TypeAlias = bool
    """
    The `Boolean` scalar type represents `true` or `false`.
    """


    ID: TypeAlias = str
    """
    The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
    """


    Int: TypeAlias = int
    """
    The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
    """


    String: TypeAlias = str
    """
    The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
    """


    @dataclass(order=True, slots=True)
    class Film:
        characters: list[Person]
        characters_ids: list[ID]
        director: String
        episode_id: Int
        id: ID
        opening_crawl: String
        planets: list[Planet]
        planets_ids: list[ID]
        release_date: String
        species: list[Species]
        species_ids: list[ID]
        starships: list[Starship]
        starships_ids: list[ID]
        title: String
        vehicles: list[Vehicle]
        vehicles_ids: list[ID]
        producer: String | None = None
        typename__: Literal['Film'] | None = 'Film'


    @dataclass(order=True, slots=True)
    class Person:
        films: list[Film]
        films_ids: list[ID]
        id: ID
        name: String
        species: list[Species]
        species_ids: list[ID]
        starships: list[Starship]
        starships_ids: list[ID]
        vehicles: list[Vehicle]
        vehicles_ids: list[ID]
        birth_year: String | None = None
        eye_color: String | None = None
        gender: String | None = None
        hair_color: String | None = None
        height: Int | None = None
        homeworld: Planet | None = None
        homeworld_id: ID | None = None
        mass: Int | None = None
        skin_color: String | None = None
        typename__: Literal['Person'] | None = 'Person'


    @dataclass(order=True, slots=True)
    class Planet:
        films: list[Film]
        films_ids: list[ID]
        id: ID
        name: String
        residents: list[Person]
        residents_ids: list[ID]
        climate: String | None = None
        diameter: String | None = None
        gravity: String | None = None
        orbital_period: String | None = None
        population: String | None = None
        rotation_period: String | None = None
        surface_water: String | None = None
        terrain: String | None = None
        typename__: Literal['Planet'] | None = 'Planet'


    @dataclass(order=True, slots=True)
    class Species:
        films: list[Film]
        films_ids: list[ID]
        id: ID
        name: String
        people: list[Person]
        people_ids: list[ID]
        average_height: String | None = None
        average_lifespan: String | None = None
        classification: String | None = None
        designation: String | None = None
        eye_colors: String | None = None
        hair_colors: String | None = None
        language: String | None = None
        skin_colors: String | None = None
        typename__: Literal['Species'] | None = 'Species'


    @dataclass(order=True, slots=True)
    class Starship:
        films: list[Film]
        films_ids: list[ID]
        id: ID
        name: String
        pilots: list[Person]
        pilots_ids: list[ID]
        MGLT: String | None = None
        cargo_capacity: String | None = None
        consumables: String | None = None
        cost_in_credits: String | None = None
        crew: String | None = None
        hyperdrive_rating: String | None = None
        length: String | None = None
        manufacturer: String | None = None
        max_atmosphering_speed: String | None = None
        model: String | None = None
        passengers: String | None = None
        starship_class: String | None = None
        typename__: Literal['Starship'] | None = 'Starship'


    @dataclass(order=True, slots=True)
    class Vehicle:
        films: list[Film]
        films_ids: list[ID]
        id: ID
        name: String
        pilots: list[Person]
        pilots_ids: list[ID]
        cargo_capacity: String | None = None
        consumables: String | None = None
        cost_in_credits: String | None = None
        crew: String | None = None
        length: String | None = None
        manufacturer: String | None = None
        max_atmosphering_speed: String | None = None
        model: String | None = None
        passengers: String | None = None
        vehicle_class: String | None = None
        typename__: Literal['Vehicle'] | None = 'Vehicle'
    ```

    <!-- fmt: on -->

---

## `--duplicate-name-suffix` {#duplicate-name-suffix}

Customize suffix for duplicate model names.

The `--duplicate-name-suffix` flag allows specifying custom suffixes for
resolving duplicate names by type. The value is a JSON mapping where keys
are type names ('model', 'enum', 'default') and values are suffix strings.
For example, `{"model": "Schema"}` changes `Item1` to `ItemSchema`.

**Related:** [`--naming-strategy`](#naming-strategy)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input input.json --duplicate-name-suffix '{"model": "Schema"}' # (1)!
    ```

    1. :material-arrow-left: `--duplicate-name-suffix` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "Order": {
          "type": "object",
          "properties": {
            "item": {
              "type": "object",
              "properties": {
                "name": {"type": "string"}
              }
            }
          }
        },
        "Cart": {
          "type": "object",
          "properties": {
            "item": {
              "type": "object",
              "properties": {
                "quantity": {"type": "integer"}
              }
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  input.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, RootModel


    class Model(RootModel[Any]):
        root: Any


    class Item(BaseModel):
        name: str | None = None


    class Order(BaseModel):
        item: Item | None = None


    class ItemSchema(BaseModel):
        quantity: int | None = None


    class Cart(BaseModel):
        item: ItemSchema | None = None
    ```

    <!-- fmt: on -->

---

## `--enable-faux-immutability` {#enable-faux-immutability}

Enable faux immutability in Pydantic models (frozen=True).

The `--enable-faux-immutability` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --enable-faux-immutability # (1)!
    ```

    1. :material-arrow-left: `--enable-faux-immutability` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  api.yaml
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel


        class Pet(BaseModel):
            model_config = ConfigDict(
                frozen=True,
            )
            id: int
            name: str
            tag: str | None = None


        class Pets(RootModel[list[Pet]]):
            model_config = ConfigDict(
                frozen=True,
            )
            root: list[Pet]


        class User(BaseModel):
            model_config = ConfigDict(
                frozen=True,
            )
            id: int
            name: str
            tag: str | None = None


        class Users(RootModel[list[User]]):
            model_config = ConfigDict(
                frozen=True,
            )
            root: list[User]


        class Id(RootModel[str]):
            model_config = ConfigDict(
                frozen=True,
            )
            root: str


        class Rules(RootModel[list[str]]):
            model_config = ConfigDict(
                frozen=True,
            )
            root: list[str]


        class Error(BaseModel):
            model_config = ConfigDict(
                frozen=True,
            )
            code: int
            message: str


        class Api(BaseModel):
            model_config = ConfigDict(
                frozen=True,
            )
            apiKey: str | None = Field(
                None, description='To be used as a dataset parameter value'
            )
            apiVersionNumber: str | None = Field(
                None, description='To be used as a version parameter value'
            )
            apiUrl: AnyUrl | None = Field(
                None, description="The URL describing the dataset's fields"
            )
            apiDocumentationUrl: AnyUrl | None = Field(
                None, description='A URL to the API console for each API'
            )


        class Apis(RootModel[list[Api]]):
            model_config = ConfigDict(
                frozen=True,
            )
            root: list[Api]


        class Event(BaseModel):
            model_config = ConfigDict(
                frozen=True,
            )
            name: str | None = None


        class Result(BaseModel):
            model_config = ConfigDict(
                frozen=True,
            )
            event: Event | None = None
        ```

        <!-- fmt: on -->

---

## `--force-optional` {#force-optional}

Force all fields to be Optional regardless of required status.

The `--force-optional` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --force-optional # (1)!
    ```

    1. :material-arrow-left: `--force-optional` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int | None = 1
        name: str | None = None
        tag: str | None = None


    class Pets(RootModel[list[Pet] | None]):
        root: list[Pet] | None = None


    class User(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None


    class Users(RootModel[list[User] | None]):
        root: list[User] | None = None


    class Id(RootModel[str | None]):
        root: str | None = None


    class Rules(RootModel[list[str] | None]):
        root: list[str] | None = None


    class Error(BaseModel):
        code: int | None = None
        message: str | None = None


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api] | None]):
        root: list[Api] | None = None


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--frozen-dataclasses` {#frozen-dataclasses}

Generate frozen dataclasses with optional keyword-only fields.

The `--frozen-dataclasses` flag generates dataclass instances that are immutable
(frozen=True). Combined with `--keyword-only` (Python 3.10+), all fields become
keyword-only arguments.

**Related:** [`--keyword-only`](#keyword-only), [`--output-model-type`](#output-model-type)

**See also:** [Output Model Types](../output-model-types.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input simple_frozen_test.json --output-model-type dataclasses.dataclass --frozen-dataclasses # (1)!
    ```

    1. :material-arrow-left: `--frozen-dataclasses` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "title": "User",
      "properties": {
        "name": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        },
        "email": {
          "type": "string",
          "format": "email"
        }
      },
      "required": ["name", "age"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  simple_frozen_test.json
    #   timestamp: 1985-10-26T08:21:00+00:00

    from __future__ import annotations

    from dataclasses import dataclass


    @dataclass(frozen=True)
    class User:
        name: str
        age: int
        email: str | None = None
    ```

    <!-- fmt: on -->

---

## `--keep-model-order` {#keep-model-order}

Keep generated model order deterministic while respecting dependency constraints.

The `--keep-model-order` flag produces a stable, deterministic output order. The
generator starts from class-name order and only moves models when required to
satisfy dependency or runtime constraints (for example, a base class must appear
before its subclass, and cyclic groups must stay together).

This option is not equivalent to preserving the raw definition order from the
input schema, and it does not guarantee a strict unconditional alphabetical
order either. Inheritance and other runtime ordering requirements can force a
non-alphabetical arrangement. The value of the flag is that repeated runs on the
same schema produce the same ordering, which keeps diffs stable.

**Related:** [`--collapse-root-models`](#collapse-root-models)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input inheritance_forward_ref.json --keep-model-order # (1)!
    ```

    1. :material-arrow-left: `--keep-model-order` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
        "title": "PersonsBestFriend",
        "description": "This is the main model.",
        "type": "object",
        "properties": {
          "people": {
            "title": "People",
            "type": "array",
            "items": {
              "$ref": "#/definitions/Person"
            }
          },
          "dogs": {
            "title": "Dogs",
            "type": "array",
            "items": {
              "$ref": "#/definitions/Dog"
            }
          },
          "dog_base": {
            "$ref": "#/definitions/DogBase"
          },
          "dog_relationships": {
            "$ref": "#/definitions/DogRelationships"
          },
          "person_base": {
            "$ref": "#/definitions/PersonBase"
          },
          "person_relationships": {
            "$ref": "#/definitions/PersonRelationships"
          }
        },
        "definitions": {
          "Person": {
            "title": "Person",
            "allOf": [
                {"$ref": "#/definitions/PersonBase"},
                {"$ref": "#/definitions/PersonRelationships"}
            ]
          },
          "Dog": {
            "title": "Dog",
            "allOf": [
                {"$ref": "#/definitions/DogBase"},
                {"$ref": "#/definitions/DogRelationships"}
            ]
          },
          "DogBase": {
            "title": "DogBase",
            "type": "object",
            "properties": {
              "name": {
                "title": "Name",
                "type": "string"
              },
              "woof": {
                "title": "Woof",
                "default": true,
                "type": "boolean"
              }
            }
          },
          "DogRelationships": {
            "title": "DogRelationships",
            "type": "object",
            "properties": {
              "people": {
                "title": "People",
                "type": "array",
                "items": {
                  "$ref": "#/definitions/Person"
                }
              }
            }
          },
          "PersonBase": {
            "title": "PersonBase",
            "type": "object",
            "properties": {
              "name": {
                "title": "Name",
                "type": "string"
              }
            }
          },
          "PersonRelationships": {
            "title": "PersonRelationships",
            "type": "object",
            "properties": {
              "people": {
                "title": "People",
                "type": "array",
                "items": {
                  "$ref": "#/definitions/Person"
                }
              }
            }
          }
        }
      }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  inheritance_forward_ref.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field


    class DogBase(BaseModel):
        name: str | None = Field(None, title='Name')
        woof: bool | None = Field(True, title='Woof')


    class DogRelationships(BaseModel):
        people: list[Person] | None = Field(None, title='People')


    class Dog(DogBase, DogRelationships):
        pass


    class PersonBase(BaseModel):
        name: str | None = Field(None, title='Name')


    class PersonRelationships(BaseModel):
        people: list[Person] | None = Field(None, title='People')


    class Person(PersonBase, PersonRelationships):
        pass


    class PersonsBestFriend(BaseModel):
        people: list[Person] | None = Field(None, title='People')
        dogs: list[Dog] | None = Field(None, title='Dogs')
        dog_base: DogBase | None = None
        dog_relationships: DogRelationships | None = None
        person_base: PersonBase | None = None
        person_relationships: PersonRelationships | None = None


    DogRelationships.model_rebuild()
    Dog.model_rebuild()
    PersonRelationships.model_rebuild()
    Person.model_rebuild()
    ```

    <!-- fmt: on -->

---

## `--keyword-only` {#keyword-only}

Generate dataclasses with keyword-only fields (Python 3.10+).

The `--keyword-only` flag generates dataclasses where all fields must be
specified as keyword arguments (kw_only=True). This is only available for
Python 3.10+. When combined with `--frozen-dataclasses`, it creates immutable
dataclasses with keyword-only arguments, improving code clarity and preventing
positional argument errors.

**Related:** [`--frozen-dataclasses`](#frozen-dataclasses), [`--output-model-type`](#output-model-type), [`--target-python-version`](#target-python-version)

**See also:** [Output Model Types](../output-model-types.md)

**Option relationships:**

- **Requires:** [`--target-python-version`](model-customization.md#target-python-version) = `3.10+` - `--keyword-only` requires `--target-python-version` 3.10 or higher for dataclasses.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input simple-star-wars.graphql --output-model-type dataclasses.dataclass --frozen-dataclasses --keyword-only --target-python-version 3.10 # (1)!
    ```

    1. :material-arrow-left: `--keyword-only` - the option documented here

??? example "Examples"

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "title": "Person",
          "type": "object",
          "properties": {
            "firstName": {
              "type": "string",
              "description": "The person's first name."
            },
            "lastName": {
              "type": ["string", "null"],
              "description": "The person's last name."
            },
            "age": {
              "description": "Age in years which must be equal to or greater than zero.",
              "type": "integer",
              "minimum": 0
            },
            "friends": {
              "type": "array"
            },
            "comment": {
              "type": "null"
            }
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  person.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from dataclasses import dataclass
        from typing import Any


        @dataclass(frozen=True, kw_only=True)
        class Person:
            firstName: str | None = None
            lastName: str | None = None
            age: int | None = None
            friends: list[Any] | None = None
            comment: None = None
        ```

        <!-- fmt: on -->

    === "GraphQL"

        **Input Schema:**

        ```graphql
        type Person {
            id: ID!
            name: String!
            height: Int
            mass: Int
            hair_color: String
            skin_color: String
            eye_color: String
            birth_year: String
            gender: String

            # Relationships
            homeworld_id: ID
            homeworld: Planet
            species: [Species!]!
            species_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
            starships: [Starship!]!
            starships_ids: [ID!]!
            vehicles: [Vehicle!]!
            vehicles_ids: [ID!]!
        }

        type Planet {
            id: ID!
            name: String!
            rotation_period: String
            orbital_period: String
            diameter: String
            climate: String
            gravity: String
            terrain: String
            surface_water: String
            population: String

            # Relationships
            residents: [Person!]!
            residents_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
        }

        type Species {
            id: ID!
            name: String!
            classification: String
            designation: String
            average_height: String
            skin_colors: String
            hair_colors: String
            eye_colors: String
            average_lifespan: String
            language: String

            # Relationships
            people: [Person!]!
            people_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
        }

        type Vehicle {
            id: ID!
            name: String!
            model: String
            manufacturer: String
            cost_in_credits: String
            length: String
            max_atmosphering_speed: String
            crew: String
            passengers: String
            cargo_capacity: String
            consumables: String
            vehicle_class: String

            # Relationships
            pilots: [Person!]!
            pilots_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
        }

        type Starship {
            id: ID!
            name: String!
            model: String
            manufacturer: String
            cost_in_credits: String
            length: String
            max_atmosphering_speed: String
            crew: String
            passengers: String
            cargo_capacity: String
            consumables: String
            hyperdrive_rating: String
            MGLT: String
            starship_class: String

            # Relationships
            pilots: [Person!]!
            pilots_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
        }

        type Film {
          id: ID!
          title: String!
          episode_id: Int!
          opening_crawl: String!
          director: String!
          producer: String
          release_date: String!

          # Relationships
          characters: [Person!]!
          characters_ids: [ID!]!
          planets: [Planet!]!
          planets_ids: [ID!]!
          starships: [Starship!]!
          starships_ids: [ID!]!
          vehicles: [Vehicle!]!
          vehicles_ids: [ID!]!
          species: [Species!]!
          species_ids: [ID!]!
        }

        type Query {
          planet(id: ID!): Planet
          listPlanets(page: Int): [Planet!]!
          person(id: ID!): Person
          listPeople(page: Int): [Person!]!
          species(id: ID!): Species
          listSpecies(page: Int): [Species!]!
          film(id: ID!): Film
          listFilms(page: Int): [Film!]!
          starship(id: ID!): Starship
          listStarships(page: Int): [Starship!]!
          vehicle(id: ID!): Vehicle
          listVehicles(page: Int): [Vehicle!]!
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  simple-star-wars.graphql
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from dataclasses import dataclass
        from typing import Literal, TypeAlias

        Boolean: TypeAlias = bool
        """
        The `Boolean` scalar type represents `true` or `false`.
        """


        ID: TypeAlias = str
        """
        The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
        """


        Int: TypeAlias = int
        """
        The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
        """


        String: TypeAlias = str
        """
        The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
        """


        @dataclass(frozen=True, kw_only=True)
        class Film:
            characters: list[Person]
            characters_ids: list[ID]
            director: String
            episode_id: Int
            id: ID
            opening_crawl: String
            planets: list[Planet]
            planets_ids: list[ID]
            release_date: String
            species: list[Species]
            species_ids: list[ID]
            starships: list[Starship]
            starships_ids: list[ID]
            title: String
            vehicles: list[Vehicle]
            vehicles_ids: list[ID]
            producer: String | None = None
            typename__: Literal['Film'] | None = 'Film'


        @dataclass(frozen=True, kw_only=True)
        class Person:
            films: list[Film]
            films_ids: list[ID]
            id: ID
            name: String
            species: list[Species]
            species_ids: list[ID]
            starships: list[Starship]
            starships_ids: list[ID]
            vehicles: list[Vehicle]
            vehicles_ids: list[ID]
            birth_year: String | None = None
            eye_color: String | None = None
            gender: String | None = None
            hair_color: String | None = None
            height: Int | None = None
            homeworld: Planet | None = None
            homeworld_id: ID | None = None
            mass: Int | None = None
            skin_color: String | None = None
            typename__: Literal['Person'] | None = 'Person'


        @dataclass(frozen=True, kw_only=True)
        class Planet:
            films: list[Film]
            films_ids: list[ID]
            id: ID
            name: String
            residents: list[Person]
            residents_ids: list[ID]
            climate: String | None = None
            diameter: String | None = None
            gravity: String | None = None
            orbital_period: String | None = None
            population: String | None = None
            rotation_period: String | None = None
            surface_water: String | None = None
            terrain: String | None = None
            typename__: Literal['Planet'] | None = 'Planet'


        @dataclass(frozen=True, kw_only=True)
        class Species:
            films: list[Film]
            films_ids: list[ID]
            id: ID
            name: String
            people: list[Person]
            people_ids: list[ID]
            average_height: String | None = None
            average_lifespan: String | None = None
            classification: String | None = None
            designation: String | None = None
            eye_colors: String | None = None
            hair_colors: String | None = None
            language: String | None = None
            skin_colors: String | None = None
            typename__: Literal['Species'] | None = 'Species'


        @dataclass(frozen=True, kw_only=True)
        class Starship:
            films: list[Film]
            films_ids: list[ID]
            id: ID
            name: String
            pilots: list[Person]
            pilots_ids: list[ID]
            MGLT: String | None = None
            cargo_capacity: String | None = None
            consumables: String | None = None
            cost_in_credits: String | None = None
            crew: String | None = None
            hyperdrive_rating: String | None = None
            length: String | None = None
            manufacturer: String | None = None
            max_atmosphering_speed: String | None = None
            model: String | None = None
            passengers: String | None = None
            starship_class: String | None = None
            typename__: Literal['Starship'] | None = 'Starship'


        @dataclass(frozen=True, kw_only=True)
        class Vehicle:
            films: list[Film]
            films_ids: list[ID]
            id: ID
            name: String
            pilots: list[Person]
            pilots_ids: list[ID]
            cargo_capacity: String | None = None
            consumables: String | None = None
            cost_in_credits: String | None = None
            crew: String | None = None
            length: String | None = None
            manufacturer: String | None = None
            max_atmosphering_speed: String | None = None
            model: String | None = None
            passengers: String | None = None
            vehicle_class: String | None = None
            typename__: Literal['Vehicle'] | None = 'Vehicle'
        ```

        <!-- fmt: on -->

---

## `--model-extra-keys` {#model-extra-keys}

Add model-level schema extensions to ConfigDict json_schema_extra.

The `--model-extra-keys` flag adds specified x-* extensions from the schema
to the model's ConfigDict json_schema_extra.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input model_extras.json --model-extra-keys x-custom-metadata # (1)!
    ```

    1. :material-arrow-left: `--model-extra-keys` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "ModelExtras",
      "type": "object",
      "x-custom-metadata": {"key1": "value1"},
      "x-version": 1,
      "properties": {
        "name": {"type": "string"}
      }
    }
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  model_extras.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, ConfigDict


        class ModelExtras(BaseModel):
            model_config = ConfigDict(
                json_schema_extra={'x-custom-metadata': {'key1': 'value1'}},
            )
            name: str | None = None
        ```

        <!-- fmt: on -->

---

## `--model-extra-keys-without-x-prefix` {#model-extra-keys-without-x-prefix}

Strip x- prefix from model-level schema extensions and add to ConfigDict json_schema_extra.

The `--model-extra-keys-without-x-prefix` flag adds specified x-* extensions
from the schema to the model's ConfigDict json_schema_extra with the x- prefix stripped.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input model_extras.json --model-extra-keys-without-x-prefix x-custom-metadata x-version # (1)!
    ```

    1. :material-arrow-left: `--model-extra-keys-without-x-prefix` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "ModelExtras",
      "type": "object",
      "x-custom-metadata": {"key1": "value1"},
      "x-version": 1,
      "properties": {
        "name": {"type": "string"}
      }
    }
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  model_extras.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, ConfigDict


        class ModelExtras(BaseModel):
            model_config = ConfigDict(
                json_schema_extra={'custom-metadata': {'key1': 'value1'}, 'version': 1},
            )
            name: str | None = None
        ```

        <!-- fmt: on -->

---

## `--model-name-map` {#model-name-map}

Rename generated model classes from a JSON mapping.

The `--model-name-map` option applies explicit class names to generated models.
Mapping keys can be canonical schema refs such as `#/definitions/Foo` or the
current generated class name such as `Foo1`. Values are final Python class names.

This is useful when a schema cannot be edited but generated model names must be
stable for public APIs or downstream code. Colliding mapped names fail instead
of being silently suffixed.

**Related:** [`--naming-strategy`](#naming-strategy), [`--use-title-as-name`](field-customization.md#use-title-as-name)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input model_name_map.json --model-name-map '{"#/definitions/Foo": "RenamedFoo", "Bar": "RenamedBar", "model-name": "OriginalMapped"}' # (1)!
    ```

    1. :material-arrow-left: `--model-name-map` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "item": {
          "$ref": "#/definitions/Foo"
        },
        "related": {
          "$ref": "#/definitions/Bar"
        },
        "original": {
          "$ref": "#/definitions/model-name"
        }
      },
      "definitions": {
        "Foo": {
          "type": "object",
          "properties": {
            "value": {
              "type": "string"
            }
          }
        },
        "Bar": {
          "type": "object",
          "properties": {
            "foo": {
              "$ref": "#/definitions/Foo"
            }
          }
        },
        "model-name": {
          "type": "object",
          "properties": {
            "bar": {
              "$ref": "#/definitions/Bar"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  model_name_map.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class RenamedFoo(BaseModel):
        value: str | None = None


    class RenamedBar(BaseModel):
        foo: RenamedFoo | None = None


    class OriginalMapped(BaseModel):
        bar: RenamedBar | None = None


    class Model(BaseModel):
        item: RenamedFoo | None = None
        related: RenamedBar | None = None
        original: OriginalMapped | None = None
    ```

    <!-- fmt: on -->

---

## `--naming-strategy` {#naming-strategy}

Use parent-prefixed naming strategy for duplicate model names.

The `--naming-strategy parent-prefixed` flag prefixes model names with their
parent model name when duplicates occur. For example, if both `Order` and
`Cart` have an inline `Item` definition, they become `OrderItem` and `CartItem`.

Generated clients and servers (experimental) follow the same rules for their method, argument, module, and class
names, with the resource or router group as the parent of a method and the method as the parent of an argument;
under `primary-first`, a primary name is one the root document declares.

**Related:** [`--duplicate-name-suffix`](#duplicate-name-suffix), [`--parent-scoped-naming`](#parent-scoped-naming)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input input.json --naming-strategy parent-prefixed # (1)!
    ```

    1. :material-arrow-left: `--naming-strategy` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "Order": {
          "type": "object",
          "properties": {
            "item": {
              "type": "object",
              "properties": {
                "name": {"type": "string"}
              }
            }
          }
        },
        "Cart": {
          "type": "object",
          "properties": {
            "item": {
              "type": "object",
              "properties": {
                "quantity": {"type": "integer"}
              }
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  input.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, RootModel


    class Model(RootModel[Any]):
        root: Any


    class ModelOrderItem(BaseModel):
        name: str | None = None


    class ModelOrder(BaseModel):
        item: ModelOrderItem | None = None


    class ModelCartItem(BaseModel):
        quantity: int | None = None


    class ModelCart(BaseModel):
        item: ModelCartItem | None = None
    ```

    <!-- fmt: on -->

---

## `--output-model-type` {#output-model-type}

Select the output model type (Pydantic v2, Pydantic v2 dataclass,
dataclasses, TypedDict, msgspec).

The `--output-model-type` flag specifies which Python data model framework to use
for the generated code. Supported values include `pydantic_v2.BaseModel`,
`pydantic_v2.dataclass`, `dataclasses.dataclass`, `typing.TypedDict`, and `msgspec.Struct`.

**See also:** [Output Model Types](../output-model-types.md)

**Option relationships:**

- **Implies:** When `--output-model-type=msgspec.Struct`, [`--use-annotated`](typing-customization.md#use-annotated) enabled

!!! tip "Usage"

    ```bash
    datamodel-codegen --input null_and_array.json --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--output-model-type` - the option documented here

??? example "Examples"

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
            "$schema": "http://json-schema.org/schema#",
            "type": "object",
            "properties": {
                "my_obj": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "items": {
                                "type": [
                                    "array",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "items"
                        ]
                    }
                }
            },
            "required": [
                "my_obj"
            ]
        }
        ```

        **Output:**

        === "Pydantic v2"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  null_and_array.json
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Any

            from pydantic import BaseModel


            class MyObjItem(BaseModel):
                items: list[Any] | None


            class Model(BaseModel):
                my_obj: list[MyObjItem]
            ```

            <!-- fmt: on -->

    === "GraphQL"

        **Input Schema:**

        ```graphql
        type Person {
            id: ID!
            name: String!
            height: Int
            mass: Int
            hair_color: String
            skin_color: String
            eye_color: String
            birth_year: String
            gender: String

            # Relationships
            homeworld_id: ID
            homeworld: Planet
            species: [Species!]!
            species_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
            starships: [Starship!]!
            starships_ids: [ID!]!
            vehicles: [Vehicle!]!
            vehicles_ids: [ID!]!
        }

        type Planet {
            id: ID!
            name: String!
            rotation_period: String
            orbital_period: String
            diameter: String
            climate: String
            gravity: String
            terrain: String
            surface_water: String
            population: String

            # Relationships
            residents: [Person!]!
            residents_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
        }

        type Species {
            id: ID!
            name: String!
            classification: String
            designation: String
            average_height: String
            skin_colors: String
            hair_colors: String
            eye_colors: String
            average_lifespan: String
            language: String

            # Relationships
            people: [Person!]!
            people_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
        }

        type Vehicle {
            id: ID!
            name: String!
            model: String
            manufacturer: String
            cost_in_credits: String
            length: String
            max_atmosphering_speed: String
            crew: String
            passengers: String
            cargo_capacity: String
            consumables: String
            vehicle_class: String

            # Relationships
            pilots: [Person!]!
            pilots_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
        }

        type Starship {
            id: ID!
            name: String!
            model: String
            manufacturer: String
            cost_in_credits: String
            length: String
            max_atmosphering_speed: String
            crew: String
            passengers: String
            cargo_capacity: String
            consumables: String
            hyperdrive_rating: String
            MGLT: String
            starship_class: String

            # Relationships
            pilots: [Person!]!
            pilots_ids: [ID!]!
            films: [Film!]!
            films_ids: [ID!]!
        }

        type Film {
          id: ID!
          title: String!
          episode_id: Int!
          opening_crawl: String!
          director: String!
          producer: String
          release_date: String!

          # Relationships
          characters: [Person!]!
          characters_ids: [ID!]!
          planets: [Planet!]!
          planets_ids: [ID!]!
          starships: [Starship!]!
          starships_ids: [ID!]!
          vehicles: [Vehicle!]!
          vehicles_ids: [ID!]!
          species: [Species!]!
          species_ids: [ID!]!
        }

        type Query {
          planet(id: ID!): Planet
          listPlanets(page: Int): [Planet!]!
          person(id: ID!): Person
          listPeople(page: Int): [Person!]!
          species(id: ID!): Species
          listSpecies(page: Int): [Species!]!
          film(id: ID!): Film
          listFilms(page: Int): [Film!]!
          starship(id: ID!): Starship
          listStarships(page: Int): [Starship!]!
          vehicle(id: ID!): Vehicle
          listVehicles(page: Int): [Vehicle!]!
        }
        ```

        **Output:**

        === "Pydantic v2"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  simple-star-wars.graphql
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Literal

            from pydantic import BaseModel, Field
            from typing_extensions import TypeAliasType

            Boolean = TypeAliasType("Boolean", bool)
            """
            The `Boolean` scalar type represents `true` or `false`.
            """


            ID = TypeAliasType("ID", str)
            """
            The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
            """


            Int = TypeAliasType("Int", int)
            """
            The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
            """


            String = TypeAliasType("String", str)
            """
            The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
            """


            class Film(BaseModel):
                characters: list[Person]
                characters_ids: list[ID]
                director: String
                episode_id: Int
                id: ID
                opening_crawl: String
                planets: list[Planet]
                planets_ids: list[ID]
                producer: String | None = None
                release_date: String
                species: list[Species]
                species_ids: list[ID]
                starships: list[Starship]
                starships_ids: list[ID]
                title: String
                vehicles: list[Vehicle]
                vehicles_ids: list[ID]
                typename__: Literal['Film'] | None = Field('Film', alias='__typename')


            class Person(BaseModel):
                birth_year: String | None = None
                eye_color: String | None = None
                films: list[Film]
                films_ids: list[ID]
                gender: String | None = None
                hair_color: String | None = None
                height: Int | None = None
                homeworld: Planet | None = None
                homeworld_id: ID | None = None
                id: ID
                mass: Int | None = None
                name: String
                skin_color: String | None = None
                species: list[Species]
                species_ids: list[ID]
                starships: list[Starship]
                starships_ids: list[ID]
                vehicles: list[Vehicle]
                vehicles_ids: list[ID]
                typename__: Literal['Person'] | None = Field('Person', alias='__typename')


            class Planet(BaseModel):
                climate: String | None = None
                diameter: String | None = None
                films: list[Film]
                films_ids: list[ID]
                gravity: String | None = None
                id: ID
                name: String
                orbital_period: String | None = None
                population: String | None = None
                residents: list[Person]
                residents_ids: list[ID]
                rotation_period: String | None = None
                surface_water: String | None = None
                terrain: String | None = None
                typename__: Literal['Planet'] | None = Field('Planet', alias='__typename')


            class Species(BaseModel):
                average_height: String | None = None
                average_lifespan: String | None = None
                classification: String | None = None
                designation: String | None = None
                eye_colors: String | None = None
                films: list[Film]
                films_ids: list[ID]
                hair_colors: String | None = None
                id: ID
                language: String | None = None
                name: String
                people: list[Person]
                people_ids: list[ID]
                skin_colors: String | None = None
                typename__: Literal['Species'] | None = Field('Species', alias='__typename')


            class Starship(BaseModel):
                MGLT: String | None = None
                cargo_capacity: String | None = None
                consumables: String | None = None
                cost_in_credits: String | None = None
                crew: String | None = None
                films: list[Film]
                films_ids: list[ID]
                hyperdrive_rating: String | None = None
                id: ID
                length: String | None = None
                manufacturer: String | None = None
                max_atmosphering_speed: String | None = None
                model: String | None = None
                name: String
                passengers: String | None = None
                pilots: list[Person]
                pilots_ids: list[ID]
                starship_class: String | None = None
                typename__: Literal['Starship'] | None = Field('Starship', alias='__typename')


            class Vehicle(BaseModel):
                cargo_capacity: String | None = None
                consumables: String | None = None
                cost_in_credits: String | None = None
                crew: String | None = None
                films: list[Film]
                films_ids: list[ID]
                id: ID
                length: String | None = None
                manufacturer: String | None = None
                max_atmosphering_speed: String | None = None
                model: String | None = None
                name: String
                passengers: String | None = None
                pilots: list[Person]
                pilots_ids: list[ID]
                vehicle_class: String | None = None
                typename__: Literal['Vehicle'] | None = Field('Vehicle', alias='__typename')


            Film.model_rebuild()
            Person.model_rebuild()
            ```

            <!-- fmt: on -->

        === "dataclass"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  simple-star-wars.graphql
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from dataclasses import dataclass
            from typing import Literal, TypeAlias

            Boolean: TypeAlias = bool
            """
            The `Boolean` scalar type represents `true` or `false`.
            """


            ID: TypeAlias = str
            """
            The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
            """


            Int: TypeAlias = int
            """
            The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
            """


            String: TypeAlias = str
            """
            The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
            """


            @dataclass
            class Film:
                characters: list[Person]
                characters_ids: list[ID]
                director: String
                episode_id: Int
                id: ID
                opening_crawl: String
                planets: list[Planet]
                planets_ids: list[ID]
                release_date: String
                species: list[Species]
                species_ids: list[ID]
                starships: list[Starship]
                starships_ids: list[ID]
                title: String
                vehicles: list[Vehicle]
                vehicles_ids: list[ID]
                producer: String | None = None
                typename__: Literal['Film'] | None = 'Film'


            @dataclass
            class Person:
                films: list[Film]
                films_ids: list[ID]
                id: ID
                name: String
                species: list[Species]
                species_ids: list[ID]
                starships: list[Starship]
                starships_ids: list[ID]
                vehicles: list[Vehicle]
                vehicles_ids: list[ID]
                birth_year: String | None = None
                eye_color: String | None = None
                gender: String | None = None
                hair_color: String | None = None
                height: Int | None = None
                homeworld: Planet | None = None
                homeworld_id: ID | None = None
                mass: Int | None = None
                skin_color: String | None = None
                typename__: Literal['Person'] | None = 'Person'


            @dataclass
            class Planet:
                films: list[Film]
                films_ids: list[ID]
                id: ID
                name: String
                residents: list[Person]
                residents_ids: list[ID]
                climate: String | None = None
                diameter: String | None = None
                gravity: String | None = None
                orbital_period: String | None = None
                population: String | None = None
                rotation_period: String | None = None
                surface_water: String | None = None
                terrain: String | None = None
                typename__: Literal['Planet'] | None = 'Planet'


            @dataclass
            class Species:
                films: list[Film]
                films_ids: list[ID]
                id: ID
                name: String
                people: list[Person]
                people_ids: list[ID]
                average_height: String | None = None
                average_lifespan: String | None = None
                classification: String | None = None
                designation: String | None = None
                eye_colors: String | None = None
                hair_colors: String | None = None
                language: String | None = None
                skin_colors: String | None = None
                typename__: Literal['Species'] | None = 'Species'


            @dataclass
            class Starship:
                films: list[Film]
                films_ids: list[ID]
                id: ID
                name: String
                pilots: list[Person]
                pilots_ids: list[ID]
                MGLT: String | None = None
                cargo_capacity: String | None = None
                consumables: String | None = None
                cost_in_credits: String | None = None
                crew: String | None = None
                hyperdrive_rating: String | None = None
                length: String | None = None
                manufacturer: String | None = None
                max_atmosphering_speed: String | None = None
                model: String | None = None
                passengers: String | None = None
                starship_class: String | None = None
                typename__: Literal['Starship'] | None = 'Starship'


            @dataclass
            class Vehicle:
                films: list[Film]
                films_ids: list[ID]
                id: ID
                name: String
                pilots: list[Person]
                pilots_ids: list[ID]
                cargo_capacity: String | None = None
                consumables: String | None = None
                cost_in_credits: String | None = None
                crew: String | None = None
                length: String | None = None
                manufacturer: String | None = None
                max_atmosphering_speed: String | None = None
                model: String | None = None
                passengers: String | None = None
                vehicle_class: String | None = None
                typename__: Literal['Vehicle'] | None = 'Vehicle'
            ```

            <!-- fmt: on -->

---

## `--parent-scoped-naming` {#parent-scoped-naming}

Namespace models by their parent scope to avoid naming conflicts.

The `--parent-scoped-naming` flag prefixes model names with their parent scope
(operation/path/parameter) to prevent name collisions when the same model name
appears in different contexts within an OpenAPI specification.

**Deprecated:** --parent-scoped-naming is deprecated. Use --naming-strategy parent-prefixed instead.

**Option relationships:**

- **Implies:** [`--naming-strategy`](model-customization.md#naming-strategy) = `parent-prefixed`

!!! tip "Usage"

    ```bash
    datamodel-codegen --input duplicate_models2.yaml --parent-scoped-naming --use-operation-id-as-name --openapi-scopes paths schemas parameters # (1)!
    ```

    1. :material-arrow-left: `--parent-scoped-naming` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: Get pet
          operationId: getPets
          responses:
            '200':
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pet"
      /cars:
        get:
          summary: Get car
          operationId: getCar
          responses:
            '200':
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Cars"

    components:
      schemas:
        Pet:
          required:
            - id
            - name
            - type
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
            type:
              type: string
              enum: [ 'pet' ]
            details:
              type: object
              properties:
                race: { type: string }
        Car:
          required:
            - id
            - name
            - type
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
            type:
              type: string
              enum: [ 'car' ]
            details:
              type: object
              properties:
                brand: { type: string }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  duplicate_models2.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum
    from typing import Any

    from pydantic import BaseModel, RootModel


    class PetType(Enum):
        pet = 'pet'


    class PetDetails(BaseModel):
        race: str | None = None


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None
        type: PetType
        details: PetDetails | None = None


    class CarType(Enum):
        car = 'car'


    class CarDetails(BaseModel):
        brand: str | None = None


    class Car(BaseModel):
        id: int
        name: str
        tag: str | None = None
        type: CarType
        details: CarDetails | None = None


    class Cars(RootModel[Any]):
        root: Any
    ```

    <!-- fmt: on -->

---

## `--reuse-model` {#reuse-model}

Reuse identical model definitions instead of generating duplicates.

The `--reuse-model` flag detects identical enum or model definitions
across the schema and generates a single shared definition, reducing
code duplication in the output.

**Related:** [`--collapse-root-models`](#collapse-root-models)

**See also:** [Model Reuse and Deduplication](../model-reuse.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input duplicate_enum.json --reuse-model # (1)!
    ```

    1. :material-arrow-left: `--reuse-model` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema",
      "title": "User",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "animal": {
          "type": "string",
          "enum": [
            "dog",
            "cat",
            "snake"
          ],
          "default": "dog"
        },
        "pet": {
          "type": "string",
          "enum": [
            "dog",
            "cat",
            "snake"
          ],
          "default": "cat"
        },
        "redistribute": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "static",
              "connected"
            ]
          }
        }
      },
      "definitions": {
        "redistribute": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "static",
              "connected"
            ]
          },
          "description": "Redistribute type for routes."
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  duplicate_enum.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel, Field, RootModel


    class Animal(Enum):
        dog = 'dog'
        cat = 'cat'
        snake = 'snake'


    class RedistributeEnum(Enum):
        static = 'static'
        connected = 'connected'


    class User(BaseModel):
        name: str | None = None
        animal: Animal | None = 'dog'
        pet: Animal | None = 'cat'
        redistribute: list[RedistributeEnum] | None = None


    class Redistribute(RootModel[list[RedistributeEnum]]):
        root: list[RedistributeEnum] = Field(
            ..., description='Redistribute type for routes.'
        )
    ```

    <!-- fmt: on -->

---

## `--reuse-scope` {#reuse-scope}

Scope for model reuse detection (root or tree).

The `--reuse-scope` flag configures the code generation behavior.

**See also:** [Model Reuse and Deduplication](../model-reuse.md)

**Option relationships:**

- **Requires:** When `--reuse-scope=tree`, [`--reuse-model`](model-customization.md#reuse-model) enabled - `--reuse-scope=tree` has no effect without `--reuse-model`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input reuse_scope_tree --reuse-model --reuse-scope tree # (1)!
    ```

    1. :material-arrow-left: `--reuse-scope` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    # schema_a.json
    {
      "type": "object",
      "properties": {
        "data": { "$ref": "#/$defs/SharedModel" }
      },
      "$defs": {
        "SharedModel": {
          "type": "object",
          "properties": {
            "id": { "type": "integer" },
            "name": { "type": "string" }
          }
        }
      }
    }

    # schema_b.json
    {
      "type": "object",
      "properties": {
        "info": { "$ref": "#/$defs/SharedModel" }
      },
      "$defs": {
        "SharedModel": {
          "type": "object",
          "properties": {
            "id": { "type": "integer" },
            "name": { "type": "string" }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # __init__.py
    # generated by datamodel-codegen:
    #   filename:  reuse_scope_tree
    #   timestamp: 2019-07-26T00:00:00+00:00

    # schema_a.py
    # generated by datamodel-codegen:
    #   filename:  reuse_scope_tree
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel

    from .shared import SharedModel as SharedModel_1


    class SharedModel(SharedModel_1):
        pass


    class Model(BaseModel):
        data: SharedModel | None = None

    # schema_b.py
    # generated by datamodel-codegen:
    #   filename:  schema_b.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel

    from . import shared


    class Model(BaseModel):
        info: shared.SharedModel | None = None

    # shared.py
    # generated by datamodel-codegen:
    #   filename:  shared.py
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class SharedModel(BaseModel):
        id: int | None = None
        name: str | None = None
    ```

    <!-- fmt: on -->

---

## `--skip-root-model` {#skip-root-model}

Skip generation of root model when schema contains nested definitions.

The `--skip-root-model` flag prevents generating a model for the root schema object
when the schema primarily contains reusable definitions. This is useful when the root
object is just a container for $defs and not a meaningful model itself.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input skip_root_model_test.json --output-model-type pydantic_v2.BaseModel --skip-root-model # (1)!
    ```

    1. :material-arrow-left: `--skip-root-model` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "_Placeholder",
      "type": "null",
      "$defs": {
        "Person": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "age": {"type": "integer"}
          },
          "required": ["name"]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  skip_root_model_test.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Person(BaseModel):
        name: str
        age: int | None = None
    ```

    <!-- fmt: on -->

---

## `--strict-nullable` {#strict-nullable}

Treat default field as a non-nullable field.

The `--strict-nullable` flag ensures that fields with default values are generated
with their exact schema type (non-nullable), rather than being made nullable.

This is particularly useful when combined with `--use-default` to generate models
where optional fields have defaults but cannot accept `None` values.

**Related:** [`--use-default`](#use-default)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input nullable.yaml --strict-nullable # (1)!
    ```

    1. :material-arrow-left: `--strict-nullable` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.0.3
    info:
      version: 1.0.0
      title: testapi
      license:
        name: proprietary
    servers: []
    paths: {}
    components:
      schemas:
        TopLevel:
          type: object
          properties:
            cursors:
              type: object
              properties:
                prev:
                  type: string
                  nullable: true
                next:
                  type: string
                  default: last
                index:
                  type: number
                tag:
                  type: string
              required:
              - prev
              - index
          required:
          - cursors
        User:
          type: object
          properties:
            info:
              type: object
              properties:
                name:
                  type: string
              required:
                - name
          required:
            - info
        apis:
          type: array
          nullable: true
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
                nullable: true
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
                nullable: true
        email:
          type: array
          items:
            type: object
            properties:
              author:
                type: string
              address:
                type: string
                description: email address
              description:
                type: string
                default: empty
              tag:
                type: string
            required:
              - author
              - address
        id:
          type: integer
          default: 1
        description:
          type: string
          nullable: true
          default: example
        name:
          type: string
          nullable: true
        tag:
          type: string
        notes:
          type: object
          properties:
            comments:
              type: array
              items:
                  type: string
              default_factory: list
              nullable: false
        options:
          type: object
          properties:
            comments:
              type: array
              items:
                  type: string
                  nullable: true
            oneOfComments:
               type: array
               items:
                   oneOf:
                    - type: string
                    - type: number
                   nullable: true
            simpleUnion:
              oneOf:
                - type: string
                - type: number
          required:
            - comments
            - oneOfComments
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  nullable.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Cursors(BaseModel):
        prev: str | None = Field(...)
        next: str = 'last'
        index: float
        tag: str | None = None


    class TopLevel(BaseModel):
        cursors: Cursors


    class Info(BaseModel):
        name: str


    class User(BaseModel):
        info: Info


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api] | None]):
        root: list[Api] | None = Field(...)


    class EmailItem(BaseModel):
        author: str
        address: str = Field(..., description='email address')
        description: str = 'empty'
        tag: str | None = None


    class Email(RootModel[list[EmailItem]]):
        root: list[EmailItem]


    class Id(RootModel[int]):
        root: int = 1


    class Description(RootModel[str | None]):
        root: str | None = 'example'


    class Name(RootModel[str | None]):
        root: str | None = None


    class Tag(RootModel[str]):
        root: str


    class Notes(BaseModel):
        comments: list[str] = Field(default_factory=list)


    class Options(BaseModel):
        comments: list[str | None]
        oneOfComments: list[str | float | None]
        simpleUnion: str | float | None = None
    ```

    <!-- fmt: on -->

---

## `--strip-default-none` {#strip-default-none}

Remove fields with None as default value from generated models.

The `--strip-default-none` option removes fields that have None as their default value from the
generated models. This results in cleaner model definitions by excluding optional fields that
default to None.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --strip-default-none # (1)!
    ```

    1. :material-arrow-left: `--strip-default-none` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(description='To be used as a dataset parameter value')
        apiVersionNumber: str | None = Field(
            description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(description="The URL describing the dataset's fields")
        apiDocumentationUrl: AnyUrl | None = Field(
            description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None


    class Result(BaseModel):
        event: Event | None
    ```

    <!-- fmt: on -->

---

## `--target-pydantic-version` {#target-pydantic-version}

Target Pydantic version for generated code compatibility.

The `--target-pydantic-version` flag chooses the oldest Pydantic the generated code must run on.
Output never depends on the Pydantic installed with datamodel-code-generator.

- **unset**: the newest supported feature forms, the same as `2.12`; config key naming is unchanged and keeps
  `populate_by_name=True` like `2`, and `--use-missing-sentinel` keeps the experimental `MISSING` import
- **2**: Pydantic 2.0+ compatible forms, such as `populate_by_name=True`, `Field(...)` string constraints,
  `json_schema_extra` for deprecated fields, and dictionary-key models defined first
- **2.11**: Pydantic 2.11+ forms, such as `validate_by_name=True`, `StringConstraints`,
  `Field(deprecated=True)`, and `TypeAliasType` dataclass aliases
- **2.12**: The 2.11 forms plus features that require Pydantic 2.12+, such as `--use-missing-sentinel`
- **2.14**: The 2.12 forms, with `--use-missing-sentinel` importing `MISSING` from `pydantic` instead of the
  `pydantic.experimental.missing_sentinel` path that Pydantic 2.14 deprecates, Python's regex engine for
  `bytes` patterns the Rust engine rejects, which Pydantic compiles from 2.14 on, and required
  `pydantic_v2.dataclass` fields written as `= Field(...)` placed before the fields with defaults of the same
  class, the order `inspect.signature` needs on Pydantic 2.13+

See [Output Model Types](../output-model-types.md#targeting-a-pydantic-version) for every affected form.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --target-pydantic-version 2.11 --allow-population-by-field-name --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--target-pydantic-version` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": ["string", "null"],
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  person.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, ConfigDict, Field, conint


    class Person(BaseModel):
        model_config = ConfigDict(
            validate_by_name=True,
        )
        firstName: str | None = Field(None, description="The person's first name.")
        lastName: str | None = Field(None, description="The person's last name.")
        age: conint(ge=0) | None = Field(
            None, description='Age in years which must be equal to or greater than zero.'
        )
        friends: list[Any] | None = None
        comment: None = Field(None)
    ```

    <!-- fmt: on -->

---

## `--target-python-version` {#target-python-version}

Target Python version for generated code syntax and imports.

The `--target-python-version` flag controls Python version-specific syntax:

- **Python 3.10-3.11**: Uses `X | None` union operator, `TypeAlias` annotation
- **Python 3.12+**: Uses `type` statement for type aliases
- **Python 3.13+**: Imports `ReadOnly` for read-only TypedDict keys from `typing`
- **Python 3.14+**: Native deferred annotations; `from __future__ import annotations` only when needed
- **Python 3.15+**: Imports `TypedDict` with `closed` and `extra_items` (PEP 728) from `typing`

This affects import statements and type annotation syntax in generated code.

**See also:** [CI/CD Integration](../ci-cd.md), [Output Model Types](../output-model-types.md), [Python Version Compatibility](../python-version-compatibility.md), [Root Models and Type Aliases](../root-model-and-type-alias.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --target-python-version 3.10 --use-standard-collections # (1)!
    ```

    1. :material-arrow-left: `--target-python-version` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": ["string", "null"],
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    === "Python 3.10"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  person.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Any

        from pydantic import BaseModel, Field, conint


        class Person(BaseModel):
            firstName: str | None = Field(None, description="The person's first name.")
            lastName: str | None = Field(None, description="The person's last name.")
            age: conint(ge=0) | None = Field(
                None, description='Age in years which must be equal to or greater than zero.'
            )
            friends: list[Any] | None = None
            comment: None = Field(None)
        ```

        <!-- fmt: on -->

---

## `--union-mode` {#union-mode}

Union mode for combining anyOf/oneOf schemas (smart or left_to_right).

The `--union-mode` flag sets Pydantic's `union_mode` on generated union fields.
Discriminated unions are not given a `union_mode`: Pydantic validates them by
their discriminator tag, a separate mode that cannot be combined with
`smart` or `left_to_right`.

**Option relationships:**

- **Requires:** [`--output-model-type`](model-customization.md#output-model-type) = `pydantic_v2.BaseModel` - `--union-mode` is only supported for `--output-model-type pydantic_v2.BaseModel`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input combine_any_of_object.json --union-mode left_to_right --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--union-mode` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "type": "object",
        "title": "My schema",
        "additionalProperties": true,
        "properties": {
            "AddressLine1": { "type": "string" },
            "AddressLine2": { "type": "string" },
            "City":         { "type": "string" }
        },
        "required": [ "AddressLine1" ],
        "anyOf": [
            {
                "type": "object",
                "properties": {
                    "State":   { "type": "string" },
                    "ZipCode": { "type": "string" }
                },
                "required": [ "ZipCode" ]
            },
            {
                "type": "object",
                "properties": {
                    "County":   { "type": "string" },
                    "PostCode": { "type": "string" }
                },
                "required": [ "PostCode" ]
            },
            { "$ref": "#/definitions/US" }
        ],
        "definitions": {
            "US":  {
                "type": "object",
                "properties": {
                    "County":   { "type": "string" },
                    "PostCode": { "type": "string" }
                },
                "required": [ "PostCode" ]
            }
        }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  combine_any_of_object.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, ConfigDict, Field, RootModel


    class MySchema1(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        AddressLine1: str
        AddressLine2: str | None = None
        City: str | None = None
        State: str | None = None
        ZipCode: str


    class MySchema2(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        AddressLine1: str
        AddressLine2: str | None = None
        City: str | None = None
        County: str | None = None
        PostCode: str


    class US(BaseModel):
        County: str | None = None
        PostCode: str


    class MySchema3(US):
        model_config = ConfigDict(
            extra='allow',
        )
        AddressLine1: str
        AddressLine2: str | None = None
        City: str | None = None


    class MySchema(RootModel[MySchema1 | MySchema2 | MySchema3]):
        root: MySchema1 | MySchema2 | MySchema3 = Field(
            ..., title='My schema', union_mode='left_to_right'
        )
    ```

    <!-- fmt: on -->

---

## `--use-default` {#use-default}

Use default values from schema in generated models.

The `--use-default` flag allows required fields with default values to be generated
with their defaults, making them optional to provide when instantiating the model.

When `--strict-nullable` is enabled, the field type still follows the schema's
nullability. For example, a required string field with a default is generated
as `str = 'value'`, not `str | None = 'value'`, unless the schema allows null.

**Related:** [`--strict-nullable`](#strict-nullable)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_default_with_const.json --output-model-type pydantic_v2.BaseModel --use-default # (1)!
    ```

    1. :material-arrow-left: `--use-default` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object",
        "title": "Use default with const",
        "properties": {
            "foo": {
                "const": "foo"
            },
            "bool_default": {
                "type": "boolean",
                "const": true,
                "default": false
            },
            "int_default": {
                "type": "integer",
                "const": 3,
                "default": 0
            },
            "str_default": {
                "type": "string",
                "const": "fast",
                "default": ""
            }
        }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  use_default_with_const.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Literal

    from pydantic import BaseModel


    class UseDefaultWithConst(BaseModel):
        foo: Literal['foo'] | None = None
        bool_default: Literal[True] = False
        int_default: Literal[3] = 0
        str_default: Literal['fast'] = ''
    ```

    <!-- fmt: on -->

---

## `--use-default-factory-for-optional-nested-models` {#use-default-factory-for-optional-nested-models}

Generate default_factory for optional nested model fields.

The `--use-default-factory-for-optional-nested-models` flag generates default_factory
for optional nested model fields instead of None default:
- Dataclasses: `field: Model | None = field(default_factory=Model)`
- Pydantic: `field: Model | None = Field(default_factory=Model)`
- msgspec: `field: Model | UnsetType = field(default_factory=Model)`

When a built-in generated child has required constructor fields, including inherited fields,
the field keeps its usual `None` or `UNSET` default. The child's required fields
remain required. With `--strip-default-none`, the usual omission behavior can instead
require the parent field to be supplied explicitly. Existing defaults enabled by
`--use-default` and fields excluded
from the constructor are respected. Custom root templates, decorators, and opaque
base classes keep their existing factory behavior. Constructors and validators are
not executed to determine whether a factory is usable.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input default_factory_nested_model.json --use-default-factory-for-optional-nested-models # (1)!
    ```

    1. :material-arrow-left: `--use-default-factory-for-optional-nested-models` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "name": {"type": "string"},
        "address": {"$ref": "#/$defs/Address"},
        "contact": {"$ref": "#/$defs/Contact"}
      },
      "required": ["name"],
      "$defs": {
        "Address": {
          "type": "object",
          "properties": {
            "street": {"type": "string"},
            "city": {"type": "string"}
          }
        },
        "Contact": {
          "type": "object",
          "properties": {
            "email": {"type": "string"},
            "phone": {"type": "string"}
          }
        }
      }
    }
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  default_factory_nested_model.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Address(BaseModel):
            street: str | None = None
            city: str | None = None


        class Contact(BaseModel):
            email: str | None = None
            phone: str | None = None


        class Model(BaseModel):
            name: str
            address: Address | None = Field(default_factory=Address)
            contact: Contact | None = Field(default_factory=Contact)
        ```

        <!-- fmt: on -->

    === "dataclass"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  default_factory_nested_model.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from dataclasses import dataclass, field


        @dataclass
        class Address:
            street: str | None = None
            city: str | None = None


        @dataclass
        class Contact:
            email: str | None = None
            phone: str | None = None


        @dataclass
        class Model:
            name: str
            address: Address | None = field(default_factory=Address)
            contact: Contact | None = field(default_factory=Contact)
        ```

        <!-- fmt: on -->

    === "msgspec"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  default_factory_nested_model.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from msgspec import UNSET, Struct, UnsetType, field


        class Address(Struct):
            street: str | UnsetType = UNSET
            city: str | UnsetType = UNSET


        class Contact(Struct):
            email: str | UnsetType = UNSET
            phone: str | UnsetType = UNSET


        class Model(Struct):
            name: str
            address: Address | UnsetType = field(default_factory=Address)
            contact: Contact | UnsetType = field(default_factory=Contact)
        ```

        <!-- fmt: on -->

---

## `--use-default-kwarg` {#use-default-kwarg}

Use default= keyword argument instead of positional argument for fields with defaults.

The `--use-default-kwarg` flag generates Field() declarations using `default=`
as a keyword argument instead of a positional argument for fields that have
default values.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input annotated.graphql --use-default-kwarg # (1)!
    ```

    1. :material-arrow-left: `--use-default-kwarg` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    type A {
        field: String!
        optionalField: String
        listField: [String!]!
        listOptionalField: [String]!
        optionalListField: [String!]
        optionalListOptionalField: [String]
        listListField:[[String!]!]!
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  annotated.graphql
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Literal

    from pydantic import BaseModel, Field
    from typing_extensions import TypeAliasType

    Boolean = TypeAliasType("Boolean", bool)
    """
    The `Boolean` scalar type represents `true` or `false`.
    """


    String = TypeAliasType("String", str)
    """
    The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
    """


    class A(BaseModel):
        field: String
        listField: list[String]
        listListField: list[list[String]]
        listOptionalField: list[String | None]
        optionalField: String | None = None
        optionalListField: list[String] | None = None
        optionalListOptionalField: list[String | None] | None = None
        typename__: Literal['A'] | None = Field(default='A', alias='__typename')
    ```

    <!-- fmt: on -->

---

## `--use-frozen-field` {#use-frozen-field}

Generate frozen (immutable) field definitions for readOnly properties.

The `--use-frozen-field` flag generates frozen field definitions:
- Pydantic v2: `Field(frozen=True)`
- Dataclasses: silently ignored (no frozen fields generated)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_frozen_field.json --use-frozen-field # (1)!
    ```

    1. :material-arrow-left: `--use-frozen-field` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "User",
      "type": "object",
      "required": ["id", "name", "password"],
      "properties": {
        "id": {
          "type": "integer",
          "description": "Server-generated ID",
          "readOnly": true
        },
        "name": {
          "type": "string"
        },
        "password": {
          "type": "string",
          "description": "User password",
          "writeOnly": true
        },
        "created_at": {
          "type": "string",
          "format": "date-time",
          "readOnly": true
        }
      }
    }
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  use_frozen_field.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import AwareDatetime, BaseModel, Field


        class User(BaseModel):
            id: int = Field(..., description='Server-generated ID', frozen=True)
            name: str
            password: str = Field(..., description='User password')
            created_at: AwareDatetime | None = Field(None, frozen=True)
        ```

        <!-- fmt: on -->

    === "dataclass"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  use_frozen_field.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from dataclasses import dataclass


        @dataclass
        class User:
            id: int
            name: str
            password: str
            created_at: str | None = None
        ```

        <!-- fmt: on -->

---

## `--use-generic-base-class` {#use-generic-base-class}

Generate a shared base class with model configuration to avoid repetition (DRY).

!!! tip "Usage"

    ```bash
    datamodel-codegen --input extra_fields.json --extra-fields forbid --output-model-type pydantic_v2.BaseModel --use-generic-base-class # (1)!
    ```

    1. :material-arrow-left: `--use-generic-base-class` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "title": "Test",
      "type": "object",
      "required": [
        "foo"
      ],
      "properties": {
        "foo": {
          "type": "object",
          "properties": {
            "x": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        },
        "bar": {
          "type": "object",
          "properties": {
            "y": {
              "type": "integer"
            }
          },
          "additionalProperties": false
        },
        "baz": {
          "type": "object",
          "properties": {
            "z": {
              "type": "integer"
            }
          }
        }
      },
      "additionalProperties": false
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  extra_fields.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel as _BaseModel
    from pydantic import ConfigDict


    class BaseModel(_BaseModel):
        model_config = ConfigDict(
            extra='forbid',
        )


    class Foo(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        x: int | None = None


    class Bar(BaseModel):
        model_config = ConfigDict(
            extra='forbid',
        )
        y: int | None = None


    class Baz(BaseModel):
        z: int | None = None


    class Test(BaseModel):
        model_config = ConfigDict(
            extra='forbid',
        )
        foo: Foo
        bar: Bar | None = None
        baz: Baz | None = None
    ```

    <!-- fmt: on -->

---

## `--use-missing-sentinel` {#use-missing-sentinel}

Use Pydantic's MISSING sentinel for unset optional BaseModel or dataclass fields.

The `--use-missing-sentinel` flag generates `MISSING` as the default for optional
Pydantic v2 BaseModel or dataclass fields that do not define a schema default. This
preserves the difference between an omitted field and a nullable field set to `None`.

**Related:** [`--strict-nullable`](#strict-nullable), [`--target-pydantic-version`](#target-pydantic-version)

**Option relationships:**

- **Implies:** [`--target-pydantic-version`](model-customization.md#target-pydantic-version) = `2.12`
- **Requires:** [`--output-model-type`](model-customization.md#output-model-type) - `--use-missing-sentinel` is only supported for `--output-model-type pydantic_v2.BaseModel` or `pydantic_v2.dataclass`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input missing_sentinel.json --output-model-type pydantic_v2.BaseModel --use-missing-sentinel # (1)!
    ```

    1. :material-arrow-left: `--use-missing-sentinel` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "MissingSentinel",
      "type": "object",
      "required": ["required", "requiredNullable"],
      "properties": {
        "required": {
          "type": "integer"
        },
        "requiredNullable": {
          "type": ["integer", "null"]
        },
        "unrequired": {
          "type": "integer"
        },
        "nullableUnrequired": {
          "type": ["integer", "null"]
        },
        "withDefault": {
          "type": "integer",
          "default": 1
        },
        "nullDefault": {
          "type": ["integer", "null"],
          "default": null
        },
        "aliased-field": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  missing_sentinel.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field
    from pydantic.experimental.missing_sentinel import MISSING


    class MissingSentinel(BaseModel):
        required: int
        requiredNullable: int | None
        unrequired: int | MISSING = MISSING
        nullableUnrequired: int | None | MISSING = MISSING
        withDefault: int | None = 1
        nullDefault: int | None = None
        aliased_field: str | MISSING = Field(MISSING, alias='aliased-field')
    ```

    <!-- fmt: on -->

---

## `--use-msgspec-nullable-enum-alias` {#use-msgspec-nullable-enum-alias}

Write a msgspec.Struct enum that lists null as an Enum and a nullable alias.

The `--use-msgspec-nullable-enum-alias` flag only applies to `--output-model-type msgspec.Struct`; other output
model types ignore it. Client generation (`--generate-client`) with `msgspec.Struct` models requires it.

Without the flag the output keeps the 0.83.0 form of an enum that lists `null` without `type: string` or
`nullable: true`, such as `type: [integer, "null"]` with `enum: [1, 2, null]`: an Enum class with a `None` member
such as `NoneType_None = None`. msgspec cannot decode such an Enum, because its members must be all `str` or all
`int` values, and the `IntEnum` written for `type: integer` cannot be imported at all.

With the flag the enum is written as a `type: string` or `nullable` enum is: an Enum class with an `Enum` suffix and
without the `None` member, and the schema name becomes a type alias of that class or `None`, so that msgspec decodes
the members and `null`. Code that used `Size.int_1` or `Size.NoneType_None` uses `SizeEnum.int_1` and `None`
instead. The default of a field of the enum is then its raw value, also with `--set-default-enum-member`, and an
enum that lists only `null` becomes the alias `None`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input msgspec_nullable_enum_31.yaml --use-msgspec-nullable-enum-alias --output-model-type msgspec.Struct # (1)!
    ```

    1. :material-arrow-left: `--use-msgspec-nullable-enum-alias` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Nullable enums, version: "1"}
    paths: {}
    components:
      schemas:
        Color:
          type: [string, "null"]
          enum: [red, green, null]
        Size:
          type: [integer, "null"]
          enum: [1, 2, null]
          default: 1
        Pet:
          type: object
          required: [name, color]
          properties:
            name: {type: string}
            color: {$ref: "#/components/schemas/Color"}
            size: {$ref: "#/components/schemas/Size"}
            sizes: {type: array, items: {$ref: "#/components/schemas/Size"}}
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  msgspec_nullable_enum_31.yaml

        from __future__ import annotations

        from enum import Enum
        from typing import Annotated, TypeAlias

        from msgspec import UNSET, Struct, UnsetType


        class ColorEnum(Enum):
            red = 'red'
            green = 'green'


        Color: TypeAlias = ColorEnum | None


        class SizeEnum(Enum):
            int_1 = 1
            int_2 = 2


        Size: TypeAlias = Annotated[SizeEnum | None, 1]


        class Pet(Struct):
            name: str
            color: Color
            size: Size | UnsetType = 1
            sizes: list[Size] | UnsetType = UNSET
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  msgspec_nullable_enum_31.yaml

        from __future__ import annotations

        from enum import Enum

        from msgspec import UNSET, Struct, UnsetType


        class Color(Enum):
            red = 'red'
            green = 'green'
            NoneType_None = None


        class Size(Enum):
            int_1 = 1
            int_2 = 2
            NoneType_None = None


        class Pet(Struct):
            name: str
            color: Color
            size: Size | UnsetType = 1
            sizes: list[Size] | UnsetType = UNSET
        ```

        <!-- fmt: on -->

---

## `--use-msgspec-tagged-unions` {#use-msgspec-tagged-unions}

Write a msgspec.Struct discriminated union as tagged structs as a whole.

The `--use-msgspec-tagged-unions` flag only applies to `--output-model-type msgspec.Struct`; other output model
types ignore it. Client generation (`--generate-client`) with `msgspec.Struct` models requires it.

Without the flag the output keeps the 0.83.0 form. A variant gets `tag_field`/`tag` only when its discriminator
property is a single literal (such as a `const`) equal to the discriminator value, or when a second discriminated
union uses the variant, and such a tag names the generated field, which differs from the property name when the
field is renamed. Any other variant, whose value comes from the discriminator `mapping`, an `enum` or the schema
name, keeps the discriminator as a `Literal` field: `Cat(petType='cat')` and `cat.petType` work and `Cat` decodes
alone, but msgspec raises `TypeError` for the union `Cat | Dog`, because it only decodes unions of tagged structs.

With the flag a union is tagged as a whole: every variant gets the property name of the document as `tag_field`
and its value as `tag`, so the union decodes. msgspec does not allow a field named like `tag_field`, so the
discriminator is then neither a field nor a constructor argument: `Cat(petType='cat')` raises `TypeError`,
`cat.petType` raises `AttributeError`, and `Cat` decoded alone accepts a payload without `petType`.

When a variant cannot take exactly one tag for the union, or a base or derived struct of a variant keeps the
property as a field, the union tags none of its variants and a warning names the reason: its variants keep
`Literal` fields, the ones with a `const` included. A variant that another union tags keeps that tag.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input direct.json --use-msgspec-tagged-unions --output-model-type msgspec.Struct # (1)!
    ```

    1. :material-arrow-left: `--use-msgspec-tagged-unions` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "openapi": "3.0.3",
      "info": {
        "title": "Discriminator field aliases",
        "version": "1"
      },
      "paths": {},
      "components": {
        "schemas": {
          "Cat": {
            "type": "object",
            "properties": {
              "petType": {
                "type": "string",
                "enum": [
                  "cat"
                ]
              },
              "meow": {
                "type": "string"
              }
            },
            "required": [
              "petType"
            ]
          },
          "Dog": {
            "type": "object",
            "properties": {
              "petType": {
                "type": "string",
                "enum": [
                  "dog"
                ]
              },
              "bark": {
                "type": "string"
              }
            },
            "required": [
              "petType"
            ]
          },
          "Pet": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Cat"
              },
              {
                "$ref": "#/components/schemas/Dog"
              }
            ],
            "discriminator": {
              "propertyName": "petType",
              "mapping": {
                "cat": "#/components/schemas/Cat",
                "dog": "#/components/schemas/Dog"
              }
            }
          },
          "Unrelated": {
            "type": "object",
            "properties": {
              "petType": {
                "type": "string"
              }
            }
          }
        }
      }
    }
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  direct.json

        from __future__ import annotations

        from enum import Enum
        from typing import TypeAlias

        from msgspec import UNSET, Struct, UnsetType


        class PetType(Enum):
            cat = 'cat'


        class Cat(Struct, tag_field='petType', tag='cat'):
            meow: str | UnsetType = UNSET


        class PetType1(Enum):
            dog = 'dog'


        class Dog(Struct, tag_field='petType', tag='dog'):
            bark: str | UnsetType = UNSET


        Pet: TypeAlias = Cat | Dog


        class Unrelated(Struct):
            petType: str | UnsetType = UNSET
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  direct.json

        from __future__ import annotations

        from enum import Enum
        from typing import Literal, TypeAlias

        from msgspec import UNSET, Struct, UnsetType


        class PetType(Enum):
            cat = 'cat'


        class Cat(Struct):
            petType: Literal['cat']
            meow: str | UnsetType = UNSET


        class PetType1(Enum):
            dog = 'dog'


        class Dog(Struct):
            petType: Literal['dog']
            bark: str | UnsetType = UNSET


        Pet: TypeAlias = Cat | Dog


        class Unrelated(Struct):
            petType: str | UnsetType = UNSET
        ```

        <!-- fmt: on -->

---

## `--use-one-literal-as-default` {#use-one-literal-as-default}

Use single literal value as default when enum has only one option.

The `--use-one-literal-as-default` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input enum_models.yaml --use-one-literal-as-default --enum-field-as-literal one # (1)!
    ```

    1. :material-arrow-left: `--use-one-literal-as-default` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
            - number
            - boolean
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
            kind:
              type: string
              enum: ['dog', 'cat']
            type:
              type: string
              enum: [ 'animal' ]
            number:
              type: integer
              enum: [ 1 ]
            boolean:
              type: boolean
              enum: [ true ]

        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        animal:
          type: object
          properties:
            kind:
              type: string
              enum: ['snake', 'rabbit']
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        EnumObject:
          type: object
          properties:
            type:
              enum: ['a', 'b']
              type: string
        EnumRoot:
          enum: ['a', 'b']
          type: string
        IntEnum:
          enum: [1,2]
          type: number
        AliasEnum:
          enum: [1,2,3]
          type: number
          x-enum-varnames: ['a', 'b', 'c']
        MultipleTypeEnum:
          enum: [ "red", "amber", "green", null, 42 ]
        singleEnum:
          enum: [ "pet" ]
          type: string
        arrayEnum:
          type: array
          items: [
            { enum: [ "cat" ] },
            { enum: [ "dog"]}
          ]
        nestedNullableEnum:
          type: object
          properties:
            nested_version:
              type: string
              nullable: true
              default: RC1
              description: nullable enum
              example: RC2
              enum:
                - RC1
                - RC1N
                - RC2
                - RC2N
                - RC3
                - RC4
                - null
        version:
          type: string
          nullable: true
          default: RC1
          description: nullable enum
          example: RC2
          enum:
          - RC1
          - RC1N
          - RC2
          - RC2N
          - RC3
          - RC4
          - null
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  enum_models.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum
    from typing import Literal

    from pydantic import BaseModel, Field, RootModel


    class Kind(Enum):
        dog = 'dog'
        cat = 'cat'


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None
        kind: Kind | None = None
        type: Literal['animal'] | None = None
        number: Literal[1] = 1
        boolean: Literal[True] = True


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class Kind1(Enum):
        snake = 'snake'
        rabbit = 'rabbit'


    class Animal(BaseModel):
        kind: Kind1 | None = None


    class Error(BaseModel):
        code: int
        message: str


    class Type(Enum):
        a = 'a'
        b = 'b'


    class EnumObject(BaseModel):
        type: Type | None = None


    class EnumRoot(Enum):
        a = 'a'
        b = 'b'


    class IntEnum(Enum):
        number_1 = 1
        number_2 = 2


    class AliasEnum(Enum):
        a = 1
        b = 2
        c = 3


    class MultipleTypeEnum(Enum):
        red = 'red'
        amber = 'amber'
        green = 'green'
        NoneType_None = None
        int_42 = 42


    class SingleEnum(RootModel[Literal['pet']]):
        root: Literal['pet'] = 'pet'


    class ArrayEnum(RootModel[list[Literal['cat'] | Literal['dog']]]):
        root: list[Literal['cat'] | Literal['dog']]


    class NestedVersionEnum(Enum):
        RC1 = 'RC1'
        RC1N = 'RC1N'
        RC2 = 'RC2'
        RC2N = 'RC2N'
        RC3 = 'RC3'
        RC4 = 'RC4'


    class NestedVersion(RootModel[NestedVersionEnum | None]):
        root: NestedVersionEnum | None = Field(
            'RC1', description='nullable enum', examples=['RC2']
        )


    class NestedNullableEnum(BaseModel):
        nested_version: NestedVersion | None = Field(
            'RC1', description='nullable enum', examples=['RC2'], validate_default=True
        )


    class VersionEnum(Enum):
        RC1 = 'RC1'
        RC1N = 'RC1N'
        RC2 = 'RC2'
        RC2N = 'RC2N'
        RC3 = 'RC3'
        RC4 = 'RC4'


    class Version(RootModel[VersionEnum | None]):
        root: VersionEnum | None = Field(
            'RC1', description='nullable enum', examples=['RC2']
        )
    ```

    <!-- fmt: on -->

---

## `--use-root-model-sequence-interface` {#use-root-model-sequence-interface}

Make non-null sequence-like Pydantic v2 RootModel classes implement collections.abc.Sequence.

When enabled, a RootModel whose root is list[T] or Sequence[T] inherits from Sequence[T]
and includes __iter__, __getitem__, and __len__ methods that delegate to the wrapped root value.
Scalar, optional, nullable, and RootModel type-alias outputs are unchanged.

This makes generated RootModel wrappers convenient to use anywhere a typed sequence is expected,
without unpacking `.root` at every call site:

```python
from collections.abc import Sequence

pets = Pets(root=[Pet(name="dog")])

first_pet: Pet = pets[0]
selected_pets: list[Pet] = pets[:1]
pet_names = [pet.name for pet in pets]


def render_pet_names(pets: Sequence[Pet]) -> list[str]:
    return [pet.name for pet in pets]


render_pet_names(pets)
```

When used with `--custom-template-dir`, a custom `pydantic_v2/RootModel.jinja2` template must render both
`sequence_base_class` and the helper methods using `sequence_item_type` and `sequence_slice_type`. If the custom
RootModel template does not render the sequence base class and helper methods, generation fails with an error
instead of silently ignoring this option.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input root_model_sequence_interface.json --output-model-type pydantic_v2.BaseModel --use-root-model-sequence-interface --class-name Pets # (1)!
    ```

    1. :material-arrow-left: `--use-root-model-sequence-interface` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "array",
      "items": {
        "$ref": "#/definitions/Pet"
      },
      "definitions": {
        "Pet": {
          "type": "object",
          "required": [
            "name"
          ],
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  root_model_sequence_interface.json

    from __future__ import annotations

    from collections.abc import Iterator, Sequence
    from typing import SupportsIndex, overload

    from pydantic import BaseModel, RootModel


    class Pet(BaseModel):
        name: str


    class Pets(RootModel[list[Pet]], Sequence[Pet]):
        root: list[Pet]

        def __iter__(self) -> Iterator[Pet]:
            return iter(self.root)

        @overload
        def __getitem__(self, index: SupportsIndex) -> Pet:
            pass

        @overload
        def __getitem__(self, index: slice) -> list[Pet]:
            pass

        def __getitem__(self, index: SupportsIndex | slice) -> Pet | list[Pet]:
            return self.root[index]

        def __len__(self) -> int:
            return len(self.root)
    ```

    <!-- fmt: on -->

---

## `--use-serialize-as-any` {#use-serialize-as-any}

Wrap fields with subtypes in Pydantic's SerializeAsAny.

The `--use-serialize-as-any` flag applies Pydantic v2's SerializeAsAny wrapper
to fields that have subtype relationships, ensuring proper serialization of
polymorphic types and inheritance hierarchies.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input serialize_as_any.yaml --use-serialize-as-any # (1)!
    ```

    1. :material-arrow-left: `--use-serialize-as-any` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: SerializeAsAny Test
      description: Test schema for SerializeAsAny annotation on types with subtypes
    paths: {}
    components:
      schemas:
        User:
          type: object
          description: Base user model
          properties:
            name:
              type: string
              description: User's name
          required:
            - name

        AdminUser:
          allOf:
            - $ref: '#/components/schemas/User'
            - type: object
              description: Admin user with additional permissions
              properties:
                admin_level:
                  type: integer
                  description: Admin permission level
              required:
                - admin_level

        Container:
          type: object
          description: Container that holds user references
          properties:
            admin_user_field:
              $ref: '#/components/schemas/AdminUser'
              description: Field that should not use SerializeAsAny
            user_field:
              $ref: '#/components/schemas/User'
              description: Field that should use SerializeAsAny
            user_list:
              type: array
              description: List of users that should use SerializeAsAny
              items:
                $ref: '#/components/schemas/User'
          required:
            - user_field
            - user_list
            - admin_user_field
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  serialize_as_any.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field, SerializeAsAny


    class User(BaseModel):
        name: str = Field(..., description="User's name")


    class AdminUser(User):
        admin_level: int = Field(..., description='Admin permission level')


    class Container(BaseModel):
        admin_user_field: AdminUser = Field(
            ..., description='Field that should not use SerializeAsAny'
        )
        user_field: SerializeAsAny[User] = Field(
            ..., description='Field that should use SerializeAsAny'
        )
        user_list: list[SerializeAsAny[User]] = Field(
            ..., description='List of users that should use SerializeAsAny'
        )
    ```

    <!-- fmt: on -->

---

## `--use-subclass-enum` {#use-subclass-enum}

Generate typed Enum subclasses for enums with specific field types.

The `--use-subclass-enum` flag generates Enum classes as subclasses of the
appropriate field type (int, float, bytes, str) when an enum has a specific
type, providing better type safety and IDE support.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input enums.graphql --use-subclass-enum # (1)!
    ```

    1. :material-arrow-left: `--use-subclass-enum` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    "Employee shift status"
    enum EmployeeShiftStatus {
      "not on shift"
      NOT_ON_SHIFT
      "on shift"
      ON_SHIFT
    }

    enum Color {
      RED
      GREEN
      BLUE
    }

    enum EnumWithOneField {
        FIELD
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  enums.graphql
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from typing_extensions import TypeAliasType

    Boolean = TypeAliasType("Boolean", bool)
    """
    The `Boolean` scalar type represents `true` or `false`.
    """


    String = TypeAliasType("String", str)
    """
    The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
    """


    class Color(str, Enum):
        BLUE = 'BLUE'
        GREEN = 'GREEN'
        RED = 'RED'


    class EmployeeShiftStatus(str, Enum):
        """
        Employee shift status
        """

        NOT_ON_SHIFT = 'NOT_ON_SHIFT'
        ON_SHIFT = 'ON_SHIFT'


    class EnumWithOneField(str, Enum):
        FIELD = 'FIELD'
    ```

    <!-- fmt: on -->

---

---

# Field Customization

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/field-customization/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--aliases`](#aliases) | Apply custom field and class name aliases via inline JSON or... |
| [`--capitalize-enum-members`](#capitalize-enum-members) | Capitalize enum member names to UPPER_CASE format. |
| [`--default-values`](#default-values) | Override field default values via inline JSON or a JSON file... |
| [`--deserialize-default-values`](#deserialize-default-values) | Deserialize selected direct scalar field defaults into their... |
| [`--empty-enum-field-name`](#empty-enum-field-name) | Name for empty string enum field values. |
| [`--extra-fields`](#extra-fields) | Configure how generated models handle extra fields not defin... |
| [`--field-constraints`](#field-constraints) | Generate Field() with validation constraints from schema. |
| [`--field-extra-keys`](#field-extra-keys) | Include specific extra keys in Field() definitions. |
| [`--field-extra-keys-without-x-prefix`](#field-extra-keys-without-x-prefix) | Include schema extension keys in Field() without requiring '... |
| [`--field-include-all-keys`](#field-include-all-keys) | Include all schema keys in Field() json_schema_extra. |
| [`--field-type-collision-strategy`](#field-type-collision-strategy) | Rename type class instead of field when names collide (Pydan... |
| [`--infer-union-variant-names`](#infer-union-variant-names) | Infer names for inline oneOf/anyOf object variants from lite... |
| [`--no-alias`](#no-alias) | Disable Field alias generation for non-Python-safe property ... |
| [`--no-deserialize-default-values`](#no-deserialize-default-values) | Keep serialized schema defaults instead of deserializing sel... |
| [`--original-field-name-delimiter`](#original-field-name-delimiter) | Specify delimiter for original field names when using snake-... |
| [`--remove-special-field-name-prefix`](#remove-special-field-name-prefix) | Remove the special prefix from field names. |
| [`--serialization-aliases`](#serialization-aliases) | Apply custom Pydantic v2 serialization aliases via inline JS... |
| [`--set-default-enum-member`](#set-default-enum-member) | Use the legacy flag for deserializing enum defaults. |
| [`--snake-case-field`](#snake-case-field) | Convert field names to snake_case format. |
| [`--special-field-name-prefix`](#special-field-name-prefix) | Prefix to add to special field names (like reserved keywords... |
| [`--use-attribute-docstrings`](#use-attribute-docstrings) | Generate field descriptions as attribute docstrings instead ... |
| [`--use-enum-values-in-discriminator`](#use-enum-values-in-discriminator) | Use enum values in discriminator mappings for union types. |
| [`--use-field-description`](#use-field-description) | Include schema descriptions as Field docstrings. |
| [`--use-field-description-example`](#use-field-description-example) | Add field examples to docstrings. |
| [`--use-inline-field-description`](#use-inline-field-description) | Add field descriptions as inline comments. |
| [`--use-schema-description`](#use-schema-description) | Use schema description as class docstring. |
| [`--use-serialization-alias`](#use-serialization-alias) | Use serialization_alias instead of alias for field aliasing ... |
| [`--use-single-line-docstring`](#use-single-line-docstring) | Emit short docstrings on a single line. |
| [`--use-title-as-name`](#use-title-as-name) | Use schema title as the generated class name. |

---

## 🍳 Recipes

### Normalize incoming field names

Convert source names to Python identifiers while preserving explicit alias data for runtime IO.

**Options:** [`--snake-case-field`](#snake-case-field), [`--original-field-name-delimiter`](#original-field-name-delimiter), [`--aliases`](#aliases)

### Carry schema documentation into models

Promote schema and field descriptions into generated docstrings or field metadata.

**Options:** [`--use-schema-description`](#use-schema-description), [`--use-field-description`](#use-field-description), [`--use-field-description-example`](#use-field-description-example)

---

## `--aliases` {#aliases}

Apply custom field and class name aliases via inline JSON or a JSON file path.

The `--aliases` option allows renaming fields and classes via an inline JSON object or JSON mapping file,
providing fine-grained control over generated names independent of schema definitions.

**See also:** [Field Aliases](../aliases.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --aliases openapi/aliases.json --target-python-version 3.10 # (1)!
    ```

    1. :material-arrow-left: `--aliases` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: "3.0.0"
        info:
          version: 1.0.0
          title: Swagger Petstore
          license:
            name: MIT
        servers:
          - url: http://petstore.swagger.io/v1
        paths:
          /pets:
            get:
              summary: List all pets
              operationId: listPets
              tags:
                - pets
              parameters:
                - name: limit
                  in: query
                  description: How many items to return at one time (max 100)
                  required: false
                  schema:
                    type: integer
                    format: int32
              responses:
                '200':
                  description: A paged array of pets
                  headers:
                    x-next:
                      description: A link to the next page of responses
                      schema:
                        type: string
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
            post:
              summary: Create a pet
              operationId: createPets
              tags:
                - pets
              responses:
                '201':
                  description: Null response
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
          /pets/{petId}:
            get:
              summary: Info for a specific pet
              operationId: showPetById
              tags:
                - pets
              parameters:
                - name: petId
                  in: path
                  required: true
                  description: The id of the pet to retrieve
                  schema:
                    type: string
              responses:
                '200':
                  description: Expected response to a valid request
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
            x-amazon-apigateway-integration:
              uri:
                Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
              passthroughBehavior: when_no_templates
              httpMethod: POST
              type: aws_proxy
        components:
          schemas:
            Pet:
              required:
                - id
                - name
              properties:
                id:
                  type: integer
                  format: int64
                  default: 1
                name:
                  type: string
                tag:
                  type: string
            Pets:
              type: array
              items:
                $ref: "#/components/schemas/Pet"
            Users:
              type: array
              items:
                required:
                  - id
                  - name
                properties:
                  id:
                    type: integer
                    format: int64
                  name:
                    type: string
                  tag:
                    type: string
            Id:
              type: string
            Rules:
              type: array
              items:
                type: string
            Error:
              description: error result
              required:
                - code
                - message
              properties:
                code:
                  type: integer
                  format: int32
                message:
                  type: string
            apis:
              type: array
              items:
                type: object
                properties:
                  apiKey:
                    type: string
                    description: To be used as a dataset parameter value
                  apiVersionNumber:
                    type: string
                    description: To be used as a version parameter value
                  apiUrl:
                    type: string
                    format: uri
                    description: "The URL describing the dataset's fields"
                  apiDocumentationUrl:
                    type: string
                    format: uri
                    description: A URL to the API console for each API
            Event:
              type: object
              description: Event object
              properties:
                name:
                  type: string
            Result:
                type: object
                properties:
                  event:
                    $ref: '#/components/schemas/Event'
        ```

        **Output:**

        === "msgspec"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  api.yaml
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Annotated, TypeAlias

            from msgspec import UNSET, Meta, Struct, UnsetType, field


            class Pet(Struct):
                id_: int = field(name='id')
                name_: str = field(name='name')
                tag: str | UnsetType = UNSET


            Pets: TypeAlias = list[Pet]


            class User(Struct):
                id_: int = field(name='id')
                name_: str = field(name='name')
                tag: str | UnsetType = UNSET


            Users: TypeAlias = list[User]


            Id: TypeAlias = str


            Rules: TypeAlias = list[str]


            class Error(Struct):
                code: int
                message: str


            class Api(Struct):
                apiKey: (
                    Annotated[str, Meta(description='To be used as a dataset parameter value')]
                    | UnsetType
                ) = UNSET
                apiVersionNumber: (
                    Annotated[str, Meta(description='To be used as a version parameter value')]
                    | UnsetType
                ) = UNSET
                apiUrl: (
                    Annotated[str, Meta(description="The URL describing the dataset's fields")]
                    | UnsetType
                ) = UNSET
                apiDocumentationUrl: (
                    Annotated[str, Meta(description='A URL to the API console for each API')]
                    | UnsetType
                ) = UNSET


            Apis: TypeAlias = list[Api]


            class Event(Struct):
                name_: str | UnsetType = field(name='name', default=UNSET)


            class Result(Struct):
                event: Event | UnsetType = UNSET
            ```

            <!-- fmt: on -->

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "type": "object",
          "title": "Root",
          "properties": {
            "name": {
              "type": "string"
            },
            "user": {
              "type": "object",
              "title": "User",
              "properties": {
                "name": {
                  "type": "string"
                },
                "id": {
                  "type": "integer"
                }
              }
            },
            "address": {
              "type": "object",
              "title": "Address",
              "properties": {
                "name": {
                  "type": "string"
                },
                "city": {
                  "type": "string"
                }
              }
            }
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  hierarchical_aliases.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class User(BaseModel):
            user_name: str | None = Field(None, alias='name')
            id: int | None = None


        class Address(BaseModel):
            address_name: str | None = Field(None, alias='name')
            city: str | None = None


        class Root(BaseModel):
            root_name: str | None = Field(None, alias='name')
            user: User | None = Field(None, title='User')
            address: Address | None = Field(None, title='Address')
        ```

        <!-- fmt: on -->

    === "GraphQL"

        **Input Schema:**

        ```graphql
        scalar DateTime

        type DateTimePeriod {
            from: DateTime!
            to: DateTime!
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  field-aliases.graphql
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Literal

        from pydantic import BaseModel, Field
        from typing_extensions import TypeAliasType

        Boolean = TypeAliasType("Boolean", bool)
        """
        The `Boolean` scalar type represents `true` or `false`.
        """


        DateTime = TypeAliasType("DateTime", str)


        String = TypeAliasType("String", str)
        """
        The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
        """


        class DateTimePeriod(BaseModel):
            periodFrom: DateTime = Field(..., alias='from')
            periodTo: DateTime = Field(..., alias='to')
            typename__: Literal['DateTimePeriod'] | None = Field(
                'DateTimePeriod', alias='__typename'
            )
        ```

        <!-- fmt: on -->

---

## `--capitalize-enum-members` {#capitalize-enum-members}

Capitalize enum member names to UPPER_CASE format.

The `--capitalize-enum-members` flag converts enum member names to
UPPER_CASE format (e.g., `active` becomes `ACTIVE`), following Python
naming conventions for constants.

**Aliases:** `--capitalise-enum-members` | **Related:** [`--snake-case-field`](#snake-case-field)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input many_case_enum.json --capitalize-enum-members # (1)!
    ```

    1. :material-arrow-left: `--capitalize-enum-members` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "string",
      "enum": [
        "snake_case",
        "CAP_CASE",
        "CamelCase",
        "UPPERCASE"
      ]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  many_case_enum.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum


    class Model(Enum):
        SNAKE_CASE = 'snake_case'
        CAP_CASE = 'CAP_CASE'
        CAMEL_CASE = 'CamelCase'
        UPPERCASE = 'UPPERCASE'
    ```

    <!-- fmt: on -->

---

## `--default-values` {#default-values}

Override field default values via inline JSON or a JSON file path.

The `--default-values` option allows specifying default values for fields via an inline JSON object or JSON file.
Supports scoped format (ClassName.field) for hierarchical overrides.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input default_values_override.json --default-values default_values/scoped_defaults.json # (1)!
    ```

    1. :material-arrow-left: `--default-values` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "User": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "status": {
              "type": "string"
            },
            "page": {
              "type": "integer"
            }
          },
          "required": ["name"]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  default_values_override.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, RootModel


    class Model(RootModel[Any]):
        root: Any


    class User(BaseModel):
        name: str
        status: str | None = 'active'
        page: int | None = 1
    ```

    <!-- fmt: on -->

---

## `--deserialize-default-values` {#deserialize-default-values}

Deserialize selected direct scalar field defaults into their generated Python types.

The `--deserialize-default-values` option accepts an explicit list of generated value types. For example,
`--deserialize-default-values decimal` emits a direct Decimal field's valid string default as a `Decimal` value,
while `--deserialize-default-values enum` emits matching scalar and list defaults as enum members. Defaults that
cannot be deserialized remain serialized so the generated module stays importable.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input serialized_decimal_defaults.json --deserialize-default-values decimal --target-python-version 3.10 # (1)!
    ```

    1. :material-arrow-left: `--deserialize-default-values` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Invoice",
      "type": "object",
      "properties": {
        "amount": {
          "type": "string",
          "format": "decimal",
          "default": "12.340"
        },
        "invalid_amount": {
          "type": "string",
          "format": "decimal",
          "default": "not-a-decimal"
        },
        "nullable_amount": {
          "type": ["string", "null"],
          "format": "decimal",
          "default": null
        },
        "label": {
          "type": "string",
          "default": "retail"
        }
      }
    }
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  serialized_decimal_defaults.json

        from __future__ import annotations

        from decimal import Decimal

        from pydantic import BaseModel


        class Invoice(BaseModel):
            amount: Decimal | None = Decimal('12.340')
            invalid_amount: Decimal | None = 'not-a-decimal'
            nullable_amount: Decimal | None = None
            label: str | None = 'retail'
        ```

        <!-- fmt: on -->

    === "Pydantic v2 dataclass"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  serialized_decimal_defaults.json

        from __future__ import annotations

        from decimal import Decimal

        from pydantic.dataclasses import dataclass


        @dataclass
        class Invoice:
            amount: Decimal | None = Decimal('12.340')
            invalid_amount: Decimal | None = 'not-a-decimal'
            nullable_amount: Decimal | None = None
            label: str | None = 'retail'
        ```

        <!-- fmt: on -->

    === "dataclass"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  serialized_decimal_defaults.json

        from __future__ import annotations

        from dataclasses import dataclass
        from decimal import Decimal


        @dataclass
        class Invoice:
            amount: Decimal | None = Decimal('12.340')
            invalid_amount: Decimal | None = 'not-a-decimal'
            nullable_amount: Decimal | None = None
            label: str | None = 'retail'
        ```

        <!-- fmt: on -->

    === "TypedDict"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  serialized_decimal_defaults.json

        from __future__ import annotations

        from decimal import Decimal
        from typing import TypedDict

        from typing_extensions import NotRequired


        class Invoice(TypedDict):
            amount: NotRequired[Decimal]
            invalid_amount: NotRequired[Decimal]
            nullable_amount: NotRequired[Decimal | None]
            label: NotRequired[str]
        ```

        <!-- fmt: on -->

    === "msgspec"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  serialized_decimal_defaults.json

        from __future__ import annotations

        from decimal import Decimal

        from msgspec import UNSET, Struct, UnsetType


        class Invoice(Struct):
            amount: Decimal | UnsetType = Decimal('12.340')
            invalid_amount: Decimal | UnsetType = 'not-a-decimal'
            nullable_amount: Decimal | None | UnsetType = UNSET
            label: str | UnsetType = 'retail'
        ```

        <!-- fmt: on -->

---

## `--empty-enum-field-name` {#empty-enum-field-name}

Name for empty string enum field values.

The `--empty-enum-field-name` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input special_enum.json --empty-enum-field-name empty # (1)!
    ```

    1. :material-arrow-left: `--empty-enum-field-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "string",
      "enum": [
        true,
        false,
        "",
        "\n",
        "\r\n",
        "\t",
        "\\x08",
        null,
        "\\"
      ]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  special_enum.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import RootModel


    class ModelEnum(Enum):
        True_ = True
        False_ = False
        empty = ''
        field_ = '\n'
        field__ = '\r\n'
        field__1 = '\t'
        field_x08 = '\\x08'
        field__2 = '\\'


    class Model(RootModel[ModelEnum | None]):
        root: ModelEnum | None = None
    ```

    <!-- fmt: on -->

---

## `--extra-fields` {#extra-fields}

Configure how generated models handle extra fields not defined in schema.

The `--extra-fields` flag sets the generated models to allow, forbid, or
ignore extra fields. With `--extra-fields allow`, models will accept and
store fields not defined in the schema. Options: allow, ignore, forbid.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input simple-star-wars.graphql --extra-fields allow # (1)!
    ```

    1. :material-arrow-left: `--extra-fields` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    type Person {
        id: ID!
        name: String!
        height: Int
        mass: Int
        hair_color: String
        skin_color: String
        eye_color: String
        birth_year: String
        gender: String

        # Relationships
        homeworld_id: ID
        homeworld: Planet
        species: [Species!]!
        species_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
        starships: [Starship!]!
        starships_ids: [ID!]!
        vehicles: [Vehicle!]!
        vehicles_ids: [ID!]!
    }

    type Planet {
        id: ID!
        name: String!
        rotation_period: String
        orbital_period: String
        diameter: String
        climate: String
        gravity: String
        terrain: String
        surface_water: String
        population: String

        # Relationships
        residents: [Person!]!
        residents_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
    }

    type Species {
        id: ID!
        name: String!
        classification: String
        designation: String
        average_height: String
        skin_colors: String
        hair_colors: String
        eye_colors: String
        average_lifespan: String
        language: String

        # Relationships
        people: [Person!]!
        people_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
    }

    type Vehicle {
        id: ID!
        name: String!
        model: String
        manufacturer: String
        cost_in_credits: String
        length: String
        max_atmosphering_speed: String
        crew: String
        passengers: String
        cargo_capacity: String
        consumables: String
        vehicle_class: String

        # Relationships
        pilots: [Person!]!
        pilots_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
    }

    type Starship {
        id: ID!
        name: String!
        model: String
        manufacturer: String
        cost_in_credits: String
        length: String
        max_atmosphering_speed: String
        crew: String
        passengers: String
        cargo_capacity: String
        consumables: String
        hyperdrive_rating: String
        MGLT: String
        starship_class: String

        # Relationships
        pilots: [Person!]!
        pilots_ids: [ID!]!
        films: [Film!]!
        films_ids: [ID!]!
    }

    type Film {
      id: ID!
      title: String!
      episode_id: Int!
      opening_crawl: String!
      director: String!
      producer: String
      release_date: String!

      # Relationships
      characters: [Person!]!
      characters_ids: [ID!]!
      planets: [Planet!]!
      planets_ids: [ID!]!
      starships: [Starship!]!
      starships_ids: [ID!]!
      vehicles: [Vehicle!]!
      vehicles_ids: [ID!]!
      species: [Species!]!
      species_ids: [ID!]!
    }

    type Query {
      planet(id: ID!): Planet
      listPlanets(page: Int): [Planet!]!
      person(id: ID!): Person
      listPeople(page: Int): [Person!]!
      species(id: ID!): Species
      listSpecies(page: Int): [Species!]!
      film(id: ID!): Film
      listFilms(page: Int): [Film!]!
      starship(id: ID!): Starship
      listStarships(page: Int): [Starship!]!
      vehicle(id: ID!): Vehicle
      listVehicles(page: Int): [Vehicle!]!
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  simple-star-wars.graphql
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Literal

    from pydantic import BaseModel, ConfigDict, Field
    from typing_extensions import TypeAliasType

    Boolean = TypeAliasType("Boolean", bool)
    """
    The `Boolean` scalar type represents `true` or `false`.
    """


    ID = TypeAliasType("ID", str)
    """
    The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
    """


    Int = TypeAliasType("Int", int)
    """
    The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
    """


    String = TypeAliasType("String", str)
    """
    The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
    """


    class Film(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        characters: list[Person]
        characters_ids: list[ID]
        director: String
        episode_id: Int
        id: ID
        opening_crawl: String
        planets: list[Planet]
        planets_ids: list[ID]
        producer: String | None = None
        release_date: String
        species: list[Species]
        species_ids: list[ID]
        starships: list[Starship]
        starships_ids: list[ID]
        title: String
        vehicles: list[Vehicle]
        vehicles_ids: list[ID]
        typename__: Literal['Film'] | None = Field('Film', alias='__typename')


    class Person(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        birth_year: String | None = None
        eye_color: String | None = None
        films: list[Film]
        films_ids: list[ID]
        gender: String | None = None
        hair_color: String | None = None
        height: Int | None = None
        homeworld: Planet | None = None
        homeworld_id: ID | None = None
        id: ID
        mass: Int | None = None
        name: String
        skin_color: String | None = None
        species: list[Species]
        species_ids: list[ID]
        starships: list[Starship]
        starships_ids: list[ID]
        vehicles: list[Vehicle]
        vehicles_ids: list[ID]
        typename__: Literal['Person'] | None = Field('Person', alias='__typename')


    class Planet(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        climate: String | None = None
        diameter: String | None = None
        films: list[Film]
        films_ids: list[ID]
        gravity: String | None = None
        id: ID
        name: String
        orbital_period: String | None = None
        population: String | None = None
        residents: list[Person]
        residents_ids: list[ID]
        rotation_period: String | None = None
        surface_water: String | None = None
        terrain: String | None = None
        typename__: Literal['Planet'] | None = Field('Planet', alias='__typename')


    class Species(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        average_height: String | None = None
        average_lifespan: String | None = None
        classification: String | None = None
        designation: String | None = None
        eye_colors: String | None = None
        films: list[Film]
        films_ids: list[ID]
        hair_colors: String | None = None
        id: ID
        language: String | None = None
        name: String
        people: list[Person]
        people_ids: list[ID]
        skin_colors: String | None = None
        typename__: Literal['Species'] | None = Field('Species', alias='__typename')


    class Starship(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        MGLT: String | None = None
        cargo_capacity: String | None = None
        consumables: String | None = None
        cost_in_credits: String | None = None
        crew: String | None = None
        films: list[Film]
        films_ids: list[ID]
        hyperdrive_rating: String | None = None
        id: ID
        length: String | None = None
        manufacturer: String | None = None
        max_atmosphering_speed: String | None = None
        model: String | None = None
        name: String
        passengers: String | None = None
        pilots: list[Person]
        pilots_ids: list[ID]
        starship_class: String | None = None
        typename__: Literal['Starship'] | None = Field('Starship', alias='__typename')


    class Vehicle(BaseModel):
        model_config = ConfigDict(
            extra='allow',
        )
        cargo_capacity: String | None = None
        consumables: String | None = None
        cost_in_credits: String | None = None
        crew: String | None = None
        films: list[Film]
        films_ids: list[ID]
        id: ID
        length: String | None = None
        manufacturer: String | None = None
        max_atmosphering_speed: String | None = None
        model: String | None = None
        name: String
        passengers: String | None = None
        pilots: list[Person]
        pilots_ids: list[ID]
        vehicle_class: String | None = None
        typename__: Literal['Vehicle'] | None = Field('Vehicle', alias='__typename')


    Film.model_rebuild()
    Person.model_rebuild()
    ```

    <!-- fmt: on -->

---

## `--field-constraints` {#field-constraints}

Generate Field() with validation constraints from schema.

The `--field-constraints` flag generates Pydantic Field() definitions with
validation constraints (min/max length, pattern, etc.) from the schema.

**Related:** [`--strict-types`](typing-customization.md#strict-types)

**See also:** [Field Constraints](../field-constraints.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api_constrained.yaml --field-constraints # (1)!
    ```

    1. :material-arrow-left: `--field-constraints` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: "3.0.0"
        info:
          version: 1.0.0
          title: Swagger Petstore
          license:
            name: MIT
        servers:
          - url: http://petstore.swagger.io/v1
        paths:
          /pets:
            get:
              summary: List all pets
              operationId: listPets
              tags:
                - pets
              parameters:
                - name: limit
                  in: query
                  description: How many items to return at one time (max 100)
                  required: false
                  schema:
                    type: integer
                    format: int32
                    minimum: 0
                    maximum: 100
              responses:
                '200':
                  description: A paged array of pets
                  headers:
                    x-next:
                      description: A link to the next page of responses
                      schema:
                        type: string
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
            post:
              summary: Create a pet
              operationId: createPets
              tags:
                - pets
              responses:
                '201':
                  description: Null response
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
          /pets/{petId}:
            get:
              summary: Info for a specific pet
              operationId: showPetById
              tags:
                - pets
              parameters:
                - name: petId
                  in: path
                  required: true
                  description: The id of the pet to retrieve
                  schema:
                    type: string
              responses:
                '200':
                  description: Expected response to a valid request
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
            x-amazon-apigateway-integration:
              uri:
                Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
              passthroughBehavior: when_no_templates
              httpMethod: POST
              type: aws_proxy
        components:
          schemas:
            Pet:
              required:
                - id
                - name
              properties:
                id:
                  type: integer
                  format: int64
                  minimum: 0
                  maximum: 9223372036854775807
                name:
                  type: string
                  maxLength: 256
                tag:
                  type: string
                  maxLength: 64
            Pets:
              type: array
              items:
                $ref: "#/components/schemas/Pet"
              maxItems: 10
              minItems: 1
              uniqueItems: true
            UID:
              type: integer
              minimum: 0
            Users:
              type: array
              items:
                required:
                  - id
                  - name
                  - uid
                properties:
                  id:
                    type: integer
                    format: int64
                    minimum: 0
                  name:
                    type: string
                    maxLength: 256
                  tag:
                    type: string
                    maxLength: 64
                  uid:
                    $ref: '#/components/schemas/UID'
                  phones:
                    type: array
                    items:
                      type: string
                      minLength: 3
                    maxItems: 10
                  fax:
                    type: array
                    items:
                      type: string
                      minLength: 3
                  height:
                    type:
                      - integer
                      - number
                    minimum: 1
                    maximum: 300
                  weight:
                    type:
                      - number
                      - integer
                    minimum: 1.0
                    maximum: 1000.0
                  age:
                    type: integer
                    minimum: 0.0
                    maximum: 200.0
                    exclusiveMinimum: true
                  rating:
                    type: number
                    minimum: 0
                    exclusiveMinimum: true
                    maximum: 5

            Id:
              type: string
            Rules:
              type: array
              items:
                type: string
            Error:
              required:
                - code
                - message
              properties:
                code:
                  type: integer
                  format: int32
                message:
                  type: string
            apis:
              type: array
              items:
                type: object
                properties:
                  apiKey:
                    type: string
                    description: To be used as a dataset parameter value
                  apiVersionNumber:
                    type: string
                    description: To be used as a version parameter value
                  apiUrl:
                    type: string
                    format: uri
                    minLength: 1
                    description: "The URL describing the dataset's fields"
                  apiDocumentationUrl:
                    type: string
                    format: uri
                    description: A URL to the API console for each API
            Event:
              type: object
              properties:
                name:
                  type: string
            Result:
                type: object
                properties:
                  event:
                    $ref: '#/components/schemas/Event'
        ```

        **Output:**

        === "Pydantic v2"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  api_constrained.yaml
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from pydantic import AnyUrl, BaseModel, Field, RootModel


            class Pet(BaseModel):
                id: int = Field(..., ge=0, le=9223372036854775807)
                name: str = Field(..., max_length=256)
                tag: str | None = Field(None, max_length=64)


            class Pets(RootModel[list[Pet]]):
                root: list[Pet] = Field(..., max_length=10, min_length=1)


            class UID(RootModel[int]):
                root: int = Field(..., ge=0)


            class Phone(RootModel[str]):
                root: str = Field(..., min_length=3)


            class FaxItem(RootModel[str]):
                root: str = Field(..., min_length=3)


            class User(BaseModel):
                id: int = Field(..., ge=0)
                name: str = Field(..., max_length=256)
                tag: str | None = Field(None, max_length=64)
                uid: UID
                phones: list[Phone] | None = Field(None, max_length=10)
                fax: list[FaxItem] | None = None
                height: int | float | None = Field(None, ge=1.0, le=300.0)
                weight: float | int | None = Field(None, ge=1.0, le=1000.0)
                age: int | None = Field(None, gt=0, le=200)
                rating: float | None = Field(None, gt=0.0, le=5.0)


            class Users(RootModel[list[User]]):
                root: list[User]


            class Id(RootModel[str]):
                root: str


            class Rules(RootModel[list[str]]):
                root: list[str]


            class Error(BaseModel):
                code: int
                message: str


            class Api(BaseModel):
                apiKey: str | None = Field(
                    None, description='To be used as a dataset parameter value'
                )
                apiVersionNumber: str | None = Field(
                    None, description='To be used as a version parameter value'
                )
                apiUrl: AnyUrl | None = Field(
                    None, description="The URL describing the dataset's fields"
                )
                apiDocumentationUrl: AnyUrl | None = Field(
                    None, description='A URL to the API console for each API'
                )


            class Apis(RootModel[list[Api]]):
                root: list[Api]


            class Event(BaseModel):
                name: str | None = None


            class Result(BaseModel):
                event: Event | None = None
            ```

            <!-- fmt: on -->

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "title": "User",
          "type": "object",
          "properties": {
                "name": {
                  "type": "string",
                  "example": "ken"
                },
                "age": {
                  "type": "integer"
                },
                "salary": {
                  "type": "integer",
                  "minimum": 0
                },
                "debt" : {
                  "type": "integer",
                  "maximum": 0
                },
                "loan" : {
                  "type": "number",
                  "maximum": 0
                },
                "tel": {
                  "type": "string",
                  "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
                },
                "height": {
                  "type": "number",
                  "minimum": 0
                },
                "weight": {
                  "type": "number",
                  "minimum": 0
                },
                "score": {
                  "type": "number",
                  "minimum": 1e-08
                },
                "active": {
                  "type": "boolean"
                },
                "photo": {
                  "type": "string",
                  "format": "binary",
                  "minLength": 100
                }
              }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  strict_types.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import (
            BaseModel,
            Field,
            StrictBool,
            StrictBytes,
            StrictFloat,
            StrictInt,
            StrictStr,
        )


        class User(BaseModel):
            name: StrictStr | None = Field(None, examples=['ken'])
            age: StrictInt | None = None
            salary: StrictInt | None = Field(None, ge=0)
            debt: StrictInt | None = Field(None, le=0)
            loan: StrictFloat | None = Field(None, le=0.0)
            tel: StrictStr | None = Field(None, pattern='^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$')
            height: StrictFloat | None = Field(None, ge=0.0)
            weight: StrictFloat | None = Field(None, ge=0.0)
            score: StrictFloat | None = Field(None, ge=1e-08)
            active: StrictBool | None = None
            photo: StrictBytes | None = Field(None, min_length=100)
        ```

        <!-- fmt: on -->

---

## `--field-extra-keys` {#field-extra-keys}

Include specific extra keys in Field() definitions.

The `--field-extra-keys` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input extras.json --field-extra-keys key2 --field-extra-keys-without-x-prefix x-repr # (1)!
    ```

    1. :material-arrow-left: `--field-extra-keys` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Extras",
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "normal key",
          "key1": 123,
          "key2": 456,
          "$exclude": 123,
          "invalid-key-1": "abc",
          "-invalid+key_2": "efg",
          "$comment": "comment",
          "$id": "#name",
          "register": "hij",
          "schema": "klm",
          "x-repr": true,
          "x-abc": true,
          "example": "example",
          "readOnly": true
        },
        "age": {
          "type": "integer",
          "example": 12,
          "writeOnly": true,
          "examples": [
            13,
            20
          ]
        },
        "status": {
          "type": "string",
          "examples": [
            "active"
          ]
        }
      }
    }
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  extras.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Extras(BaseModel):
            name: str | None = Field(
                None,
                description='normal key',
                examples=['example'],
                json_schema_extra={'key2': 456, 'invalid-key-1': 'abc'},
                repr=True,
            )
            age: int | None = Field(None, examples=[13, 20], json_schema_extra={'example': 12})
            status: str | None = Field(None, examples=['active'])
        ```

        <!-- fmt: on -->

---

## `--field-extra-keys-without-x-prefix` {#field-extra-keys-without-x-prefix}

Include schema extension keys in Field() without requiring 'x-' prefix.

The --field-extra-keys-without-x-prefix option allows you to specify custom
schema extension keys that should be included in Pydantic Field() extras without
the 'x-' prefix requirement. For example, 'x-repr' in the schema becomes 'repr'
in Field(). This is useful for custom schema extensions and vendor-specific metadata.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input extras.json --field-include-all-keys --field-extra-keys-without-x-prefix x-repr # (1)!
    ```

    1. :material-arrow-left: `--field-extra-keys-without-x-prefix` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Extras",
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "normal key",
          "key1": 123,
          "key2": 456,
          "$exclude": 123,
          "invalid-key-1": "abc",
          "-invalid+key_2": "efg",
          "$comment": "comment",
          "$id": "#name",
          "register": "hij",
          "schema": "klm",
          "x-repr": true,
          "x-abc": true,
          "example": "example",
          "readOnly": true
        },
        "age": {
          "type": "integer",
          "example": 12,
          "writeOnly": true,
          "examples": [
            13,
            20
          ]
        },
        "status": {
          "type": "string",
          "examples": [
            "active"
          ]
        }
      }
    }
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  extras.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Extras(BaseModel):
            name: str | None = Field(
                None,
                description='normal key',
                examples=['example'],
                json_schema_extra={
                    'key1': 123,
                    'key2': 456,
                    '$exclude': 123,
                    'invalid-key-1': 'abc',
                    '-invalid+key_2': 'efg',
                    '$comment': 'comment',
                    'register': 'hij',
                    'schema': 'klm',
                    'x-abc': True,
                    'readOnly': True,
                },
                repr=True,
            )
            age: int | None = Field(
                None, examples=[13, 20], json_schema_extra={'example': 12, 'writeOnly': True}
            )
            status: str | None = Field(None, examples=['active'])
        ```

        <!-- fmt: on -->

---

## `--field-include-all-keys` {#field-include-all-keys}

Include all schema keys in Field() json_schema_extra.

The `--field-include-all-keys` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --field-include-all-keys # (1)!
    ```

    1. :material-arrow-left: `--field-include-all-keys` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": ["string", "null"],
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  person.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, Field, conint


    class Person(BaseModel):
        firstName: str | None = Field(None, description="The person's first name.")
        lastName: str | None = Field(None, description="The person's last name.")
        age: conint(ge=0) | None = Field(
            None, description='Age in years which must be equal to or greater than zero.'
        )
        friends: list[Any] | None = None
        comment: None = Field(None)
    ```

    <!-- fmt: on -->

---

## `--field-type-collision-strategy` {#field-type-collision-strategy}

Rename type class instead of field when names collide (Pydantic v2 only).

The `--field-type-collision-strategy` flag controls how field name and type name
collisions are resolved. With `rename-type`, the type class is renamed with a suffix
to preserve the original field name, instead of renaming the field and adding an alias.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input field_has_same_name.json --output-model-type pydantic_v2.BaseModel --field-type-collision-strategy rename-type # (1)!
    ```

    1. :material-arrow-left: `--field-type-collision-strategy` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "title": "Test",
      "type": "object",
      "properties": {
        "TestObject": {
          "title": "TestObject",
          "type": "object",
          "properties": {
            "test_string": {
              "type": "string"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  field_has_same_name.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field


    class TestObject_1(BaseModel):
        test_string: str | None = None


    class Test(BaseModel):
        TestObject: TestObject_1 | None = Field(None, title='TestObject')
    ```

    <!-- fmt: on -->

---

## `--infer-union-variant-names` {#infer-union-variant-names}

Infer names for inline oneOf/anyOf object variants from literal fields.

The `--infer-union-variant-names` flag uses branch-local `const` values or
single-value enums on a shared discriminator-style property to name generated
inline union models. This is useful when inline union branches would otherwise
receive position-based names such as `Event` and `Event1`.

The literal value can also come from a single-value enum or an internal `$ref`.
Existing generated output is preserved unless this option is enabled.

**Related:** [`--use-title-as-name`](#use-title-as-name)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input infer_union_variant_names.json --infer-union-variant-names # (1)!
    ```

    1. :material-arrow-left: `--infer-union-variant-names` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "WebhookEnvelope",
      "type": "object",
      "required": ["event"],
      "properties": {
        "event": {
          "oneOf": [
            {
              "type": "object",
              "required": ["type", "id"],
              "properties": {
                "type": {"const": "message.created"},
                "id": {"type": "string"}
              }
            },
            {
              "type": "object",
              "required": ["type", "reason"],
              "properties": {
                "type": {"const": "message.failed"},
                "reason": {"type": "string"}
              }
            }
          ]
        }
      }
    }
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  infer_union_variant_names.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Literal

        from pydantic import BaseModel


        class EventMessageCreated(BaseModel):
            type: Literal['message.created']
            id: str


        class EventMessageFailed(BaseModel):
            type: Literal['message.failed']
            reason: str


        class WebhookEnvelope(BaseModel):
            event: EventMessageCreated | EventMessageFailed
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  infer_union_variant_names.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Literal

        from pydantic import BaseModel


        class Event(BaseModel):
            type: Literal['message.created']
            id: str


        class Event1(BaseModel):
            type: Literal['message.failed']
            reason: str


        class WebhookEnvelope(BaseModel):
            event: Event | Event1
        ```

        <!-- fmt: on -->

---

## `--no-alias` {#no-alias}

Disable Field alias generation for non-Python-safe property names.

The `--no-alias` flag disables automatic alias generation when JSON property
names contain characters invalid in Python (like hyphens). Without this flag,
fields are renamed to Python-safe names with `Field(alias='original-name')`.
With this flag, only Python-safe names are used without aliases.

**See also:** [Field Aliases](../aliases.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input no_alias.json --no-alias # (1)!
    ```

    1. :material-arrow-left: `--no-alias` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "first-name": {
          "type": "string"
        },
        "last-name": {
          "type": "string"
        },
        "email_address": {
          "type": "string"
        }
      },
      "required": ["first-name", "last-name"]
    }
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  no_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel


        class Person(BaseModel):
            first_name: str
            last_name: str
            email_address: str | None = None
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  no_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Person(BaseModel):
            first_name: str = Field(..., alias='first-name')
            last_name: str = Field(..., alias='last-name')
            email_address: str | None = None
        ```

        <!-- fmt: on -->

---

## `--no-deserialize-default-values` {#no-deserialize-default-values}

Keep serialized schema defaults instead of deserializing selected types.

The `--no-deserialize-default-values` flag explicitly disables default-value deserialization, including when a
preset enables it. Compatibility warnings still identify direct scalar defaults whose serialized form does not
match the generated Python type.

**Related:** [`--deserialize-default-values`](#deserialize-default-values), [`--preset`](base-options.md#preset)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input serialized_decimal_defaults.json --preset standard-py310-20260826 --no-deserialize-default-values --disable-timestamp --formatters builtin # (1)!
    ```

    1. :material-arrow-left: `--no-deserialize-default-values` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Invoice",
      "type": "object",
      "properties": {
        "amount": {
          "type": "string",
          "format": "decimal",
          "default": "12.340"
        },
        "invalid_amount": {
          "type": "string",
          "format": "decimal",
          "default": "not-a-decimal"
        },
        "nullable_amount": {
          "type": ["string", "null"],
          "format": "decimal",
          "default": null
        },
        "label": {
          "type": "string",
          "default": "retail"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  serialized_decimal_defaults.json

    from __future__ import annotations

    from decimal import Decimal

    from pydantic import BaseModel, ConfigDict


    class Invoice(BaseModel):
        model_config = ConfigDict(
            populate_by_name=True,
        )
        amount: Decimal = '12.340'
        invalid_amount: Decimal = 'not-a-decimal'
        nullable_amount: Decimal | None = None
        label: str = 'retail'
    ```

    <!-- fmt: on -->

---

## `--original-field-name-delimiter` {#original-field-name-delimiter}

Specify delimiter for original field names when using snake-case conversion.

The `--original-field-name-delimiter` option works with `--snake-case-field` to specify
the delimiter used in original field names. This is useful when field names contain
delimiters like spaces or hyphens that should be treated as word boundaries during
snake_case conversion.

**Option relationships:**

- **Requires:** [`--snake-case-field`](field-customization.md#snake-case-field) enabled - `--original-field-name-delimiter` can not be used without `--snake-case-field`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input space_field_enum.json --snake-case-field --original-field-name-delimiter " " # (1)!
    ```

    1. :material-arrow-left: `--original-field-name-delimiter` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "SpaceIF": {
          "$ref": "#/definitions/SpaceIF"
        }
      },
      "definitions": {
        "SpaceIF": {
          "type": "string",
          "enum": [
            "Space Field"
          ]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  space_field_enum.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel, Field


    class SpaceIF(Enum):
        space_field = 'Space Field'


    class Model(BaseModel):
        space_if: SpaceIF | None = Field(None, alias='SpaceIF')
    ```

    <!-- fmt: on -->

---

## `--remove-special-field-name-prefix` {#remove-special-field-name-prefix}

Remove the special prefix from field names.

The `--remove-special-field-name-prefix` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input special_prefix_model.json --remove-special-field-name-prefix # (1)!
    ```

    1. :material-arrow-left: `--remove-special-field-name-prefix` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
        "$id": "schema_v2.json",
        "$schema": "http://json-schema.org/schema#",

        "type": "object",
        "properties": {
            "@id": {
                "type": "string",
                "format": "uri",
                "pattern": "^http.*$",
                "title": "Id must be presesnt and must be a URI"
            },
            "@type": { "type": "string" },
            "@+!type": { "type": "string" },
            "@-!type": { "type": "string" },
            "profile": { "type": "string" }
        },
        "required": ["@id", "@type"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  special_prefix_model.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field


    class Model(BaseModel):
        id: AnyUrl = Field(..., alias='@id', title='Id must be presesnt and must be a URI')
        type: str = Field(..., alias='@type')
        type_1: str | None = Field(None, alias='@+!type')
        type_2: str | None = Field(None, alias='@-!type')
        profile: str | None = None
    ```

    <!-- fmt: on -->

---

## `--serialization-aliases` {#serialization-aliases}

Apply custom Pydantic v2 serialization aliases via inline JSON or a JSON file path.

The `--serialization-aliases` option lets Pydantic v2 models keep input aliases
or validation aliases while using separate output-only names for serialization.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input serialization_aliases.json --aliases aliases/serialization_aliases.json --serialization-aliases aliases/serialization_aliases_output.json --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--serialization-aliases` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Messaging",
      "type": "object",
      "definitions": {
        "SendMessageV2": {
          "type": "object",
          "properties": {
            "textMessage": {
              "type": "string"
            }
          },
          "required": ["textMessage"]
        },
        "OtherMessage": {
          "type": "object",
          "properties": {
            "other-name": {
              "type": "string"
            }
          },
          "required": ["other-name"]
        },
        "SameNameMessage": {
          "type": "object",
          "properties": {
            "same-name": {
              "type": "string"
            }
          },
          "required": ["same-name"]
        },
        "RequiredOnlyMessage": {
          "type": "object",
          "allOf": [
            {
              "type": "object",
              "properties": {
                "known-name": {
                  "type": "string"
                }
              },
              "required": [
                "known-name",
                "missing-required",
                "plain-missing",
                "allof-unmapped"
              ]
            }
          ],
          "required": [
            "known-name",
            "missing-required",
            "plain-missing",
            "allof-unmapped"
          ]
        },
        "RequiredOnlyGrandBase": {
          "type": "object",
          "properties": {
            "grand-name": {
              "type": "integer"
            },
            "bare-name": {}
          },
          "required": ["grand-name", "bare-name"]
        },
        "RequiredOnlyBase": {
          "type": "object",
          "properties": {
            "base-name": {
              "type": "string"
            }
          },
          "allOf": [
            {
              "$ref": "#/definitions/RequiredOnlyGrandBase"
            }
          ],
          "required": ["base-name"]
        },
        "RequiredOnlyRefMessage": {
          "type": "object",
          "properties": {
            "own-name": {
              "type": "string"
            }
          },
          "allOf": [
            {
              "$ref": "#/definitions/RequiredOnlyBase"
            }
          ],
          "required": [
            "own-name",
            "grand-name",
            "bare-name",
            "ignored-missing",
            "ref-missing-required",
            "ref-plain-missing"
          ]
        },
        "RequiredOnlyEmptyAllOfBase": {
          "type": "object",
          "allOf": [
            {
              "type": "object"
            }
          ]
        },
        "RequiredOnlyEmptyAllOfMessage": {
          "type": "object",
          "allOf": [
            {
              "$ref": "#/definitions/RequiredOnlyEmptyAllOfBase"
            }
          ],
          "required": ["empty-missing"]
        },
        "RequiredOnlyRecursiveEmptyGrandBase": {
          "type": "object",
          "properties": {
            "unrelated-name": {
              "type": "string"
            }
          }
        },
        "RequiredOnlyRecursiveEmptyBase": {
          "type": "object",
          "allOf": [
            {
              "$ref": "#/definitions/RequiredOnlyRecursiveEmptyGrandBase"
            }
          ]
        },
        "RequiredOnlyRecursiveEmptyMessage": {
          "type": "object",
          "allOf": [
            {
              "$ref": "#/definitions/RequiredOnlyRecursiveEmptyBase"
            }
          ],
          "required": ["recursive-missing"]
        }
      },
      "properties": {
        "send": {
          "$ref": "#/definitions/SendMessageV2"
        },
        "other": {
          "$ref": "#/definitions/OtherMessage"
        },
        "same": {
          "$ref": "#/definitions/SameNameMessage"
        },
        "requiredOnly": {
          "$ref": "#/definitions/RequiredOnlyMessage"
        },
        "requiredOnlyRef": {
          "$ref": "#/definitions/RequiredOnlyRefMessage"
        },
        "requiredOnlyEmptyAllOf": {
          "$ref": "#/definitions/RequiredOnlyEmptyAllOfMessage"
        },
        "requiredOnlyRecursiveEmpty": {
          "$ref": "#/definitions/RequiredOnlyRecursiveEmptyMessage"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  serialization_aliases.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import AliasChoices, BaseModel, Field


    class SendMessageV2(BaseModel):
        message: str = Field(
            ...,
            serialization_alias='messageText',
            validation_alias=AliasChoices('textMessage', 'message', 'text'),
        )


    class OtherMessage(BaseModel):
        other_name: str = Field(..., alias='other-name', serialization_alias='otherName')


    class SameNameMessage(BaseModel):
        same_name: str = Field(..., alias='same-name', serialization_alias='same_name')


    class RequiredOnlyMessage(BaseModel):
        known_name: str = Field(..., alias='known-name')
        missingRequiredInput: Any = Field(
            ...,
            serialization_alias='missingRequired',
            validation_alias=AliasChoices('missing-required', 'missingRequiredInput'),
        )
        plainMissingInput: Any = Field(
            ..., alias='plain-missing', serialization_alias='plainMissing'
        )
        allof_unmapped: Any = Field(..., alias='allof-unmapped')


    class RequiredOnlyGrandBase(BaseModel):
        grand_name: int = Field(..., alias='grand-name')
        bare_name: Any = Field(..., alias='bare-name')


    class RequiredOnlyBase(RequiredOnlyGrandBase):
        base_name: str = Field(..., alias='base-name')


    class RequiredOnlyRefMessage(RequiredOnlyBase):
        own_name: str = Field(..., alias='own-name')
        grand_name: int = Field(
            ...,
            serialization_alias='grandName',
            validation_alias=AliasChoices('grand-name', 'grandInput'),
        )
        bare_name: Any = Field(..., alias='bare-name', serialization_alias='bareName')
        ignored_missing: Any = Field(..., alias='ignored-missing')
        refMissingInput: Any = Field(
            ...,
            serialization_alias='refMissingRequired',
            validation_alias=AliasChoices('ref-missing-required', 'refMissingInput'),
        )
        refPlainMissingInput: Any = Field(
            ..., alias='ref-plain-missing', serialization_alias='refPlainMissing'
        )


    class RequiredOnlyEmptyAllOfBase(BaseModel):
        pass


    class RequiredOnlyEmptyAllOfMessage(RequiredOnlyEmptyAllOfBase):
        emptyMissingInput: Any = Field(
            ...,
            serialization_alias='emptyMissing',
            validation_alias=AliasChoices('empty-missing', 'emptyMissingInput'),
        )


    class RequiredOnlyRecursiveEmptyGrandBase(BaseModel):
        unrelated_name: str | None = Field(None, alias='unrelated-name')


    class RequiredOnlyRecursiveEmptyBase(RequiredOnlyRecursiveEmptyGrandBase):
        pass


    class RequiredOnlyRecursiveEmptyMessage(RequiredOnlyRecursiveEmptyBase):
        recursiveMissingInput: Any = Field(
            ..., alias='recursive-missing', serialization_alias='recursiveMissing'
        )


    class Messaging(BaseModel):
        send: SendMessageV2 | None = None
        other: OtherMessage | None = None
        same: SameNameMessage | None = None
        requiredOnly: RequiredOnlyMessage | None = None
        requiredOnlyRef: RequiredOnlyRefMessage | None = None
        requiredOnlyEmptyAllOf: RequiredOnlyEmptyAllOfMessage | None = None
        requiredOnlyRecursiveEmpty: RequiredOnlyRecursiveEmptyMessage | None = None
    ```

    <!-- fmt: on -->

---

## `--set-default-enum-member` {#set-default-enum-member}

Use the legacy flag for deserializing enum defaults.

The `--set-default-enum-member` flag is deprecated. Use `--deserialize-default-values enum` instead.

**Deprecated:** --set-default-enum-member is deprecated. Use --deserialize-default-values enum instead.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input duplicate_enum.json --reuse-model --set-default-enum-member # (1)!
    ```

    1. :material-arrow-left: `--set-default-enum-member` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema",
      "title": "User",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "animal": {
          "type": "string",
          "enum": [
            "dog",
            "cat",
            "snake"
          ],
          "default": "dog"
        },
        "pet": {
          "type": "string",
          "enum": [
            "dog",
            "cat",
            "snake"
          ],
          "default": "cat"
        },
        "redistribute": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "static",
              "connected"
            ]
          }
        }
      },
      "definitions": {
        "redistribute": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "static",
              "connected"
            ]
          },
          "description": "Redistribute type for routes."
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  duplicate_enum.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel, Field, RootModel


    class Animal(Enum):
        dog = 'dog'
        cat = 'cat'
        snake = 'snake'


    class RedistributeEnum(Enum):
        static = 'static'
        connected = 'connected'


    class User(BaseModel):
        name: str | None = None
        animal: Animal | None = Animal.dog
        pet: Animal | None = Animal.cat
        redistribute: list[RedistributeEnum] | None = None


    class Redistribute(RootModel[list[RedistributeEnum]]):
        root: list[RedistributeEnum] = Field(
            ..., description='Redistribute type for routes.'
        )
    ```

    <!-- fmt: on -->

---

## `--snake-case-field` {#snake-case-field}

Convert field names to snake_case format.

The `--snake-case-field` flag converts camelCase or PascalCase field names
to snake_case format in the generated Python code, following Python naming
conventions (PEP 8).

**Related:** [`--capitalize-enum-members`](#capitalize-enum-members)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input invalid_enum_name.json --snake-case-field # (1)!
    ```

    1. :material-arrow-left: `--snake-case-field` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "InvalidEnum",
      "type": "string",
      "enum": [
        "1 value",
        " space",
        "*- special",
        "schema",
        "MRO",
        "mro"
      ]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  invalid_enum_name.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum


    class InvalidEnum(Enum):
        field_1_value = '1 value'
        field_space = ' space'
        field___special = '*- special'
        schema = 'schema'
        mro_1 = 'MRO'
        mro_ = 'mro'
    ```

    <!-- fmt: on -->

---

## `--special-field-name-prefix` {#special-field-name-prefix}

Prefix to add to special field names (like reserved keywords).

The `--special-field-name-prefix` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input special_enum.json --special-field-name-prefix special # (1)!
    ```

    1. :material-arrow-left: `--special-field-name-prefix` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "string",
      "enum": [
        true,
        false,
        "",
        "\n",
        "\r\n",
        "\t",
        "\\x08",
        null,
        "\\"
      ]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  special_enum.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import RootModel


    class ModelEnum(Enum):
        True_ = True
        False_ = False
        special_ = ''
        special__1 = '\n'
        special__ = '\r\n'
        special__2 = '\t'
        special_x08 = '\\x08'
        special__3 = '\\'


    class Model(RootModel[ModelEnum | None]):
        root: ModelEnum | None = None
    ```

    <!-- fmt: on -->

---

## `--use-attribute-docstrings` {#use-attribute-docstrings}

Generate field descriptions as attribute docstrings instead of Field descriptions.

The `--use-attribute-docstrings` flag places field descriptions in Python docstring
format (PEP 224 attribute docstrings) rather than in Field(..., description=...).
This provides better IDE support for hovering over attributes. Requires
`--use-field-description` to be enabled.

**Related:** [`--use-field-description`](#use-field-description)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_attribute_docstrings_test.json --output-model-type pydantic_v2.BaseModel --use-field-description --use-attribute-docstrings # (1)!
    ```

    1. :material-arrow-left: `--use-attribute-docstrings` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "title": "Person",
      "properties": {
        "name": {
          "type": "string",
          "description": "The person's full name"
        },
        "age": {
          "type": "integer",
          "description": "The person's age in years"
        }
      },
      "required": ["name"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  use_attribute_docstrings_test.json
    #   timestamp: 1985-10-26T08:21:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, ConfigDict


    class Person(BaseModel):
        model_config = ConfigDict(
            use_attribute_docstrings=True,
        )
        name: str
        """
        The person's full name
        """
        age: int | None = None
        """
        The person's age in years
        """
    ```

    <!-- fmt: on -->

---

## `--use-enum-values-in-discriminator` {#use-enum-values-in-discriminator}

Use enum values in discriminator mappings for union types.

The `--use-enum-values-in-discriminator` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input discriminator_enum.yaml --use-enum-values-in-discriminator --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--use-enum-values-in-discriminator` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    components:
      schemas:
        Request:
          oneOf:
            - $ref: '#/components/schemas/RequestV1'
            - $ref: '#/components/schemas/RequestV2'
          discriminator:
            propertyName: version
            mapping:
              v1: '#/components/schemas/RequestV1'
              v2: '#/components/schemas/RequestV2'

        RequestVersionEnum:
          type: string
          description: this is not included!
          title: no title!
          enum:
            - v1
            - v2
        RequestBase:
          properties:
            version:
              $ref: '#/components/schemas/RequestVersionEnum'
          required:
            - version

        RequestV1:
          allOf:
            - $ref: '#/components/schemas/RequestBase'
          properties:
            request_id:
              type: string
              title: test title
              description: there is description
          required:
            - request_id
        RequestV2:
          allOf:
            - $ref: '#/components/schemas/RequestBase'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  discriminator_enum.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum
    from typing import Literal

    from pydantic import BaseModel, Field, RootModel


    class RequestVersionEnum(Enum):
        v1 = 'v1'
        v2 = 'v2'


    class RequestBase(BaseModel):
        version: RequestVersionEnum


    class RequestV1(RequestBase):
        request_id: str = Field(..., description='there is description', title='test title')
        version: Literal[RequestVersionEnum.v1]


    class RequestV2(RequestBase):
        version: Literal[RequestVersionEnum.v2]


    class Request(RootModel[RequestV1 | RequestV2]):
        root: RequestV1 | RequestV2 = Field(..., discriminator='version')
    ```

    <!-- fmt: on -->

---

## `--use-field-description` {#use-field-description}

Include schema descriptions as Field docstrings.

The `--use-field-description` flag extracts the `description` property from
schema fields and includes them as docstrings or Field descriptions in the
generated models, preserving documentation from the original schema.

**Related:** [`--use-inline-field-description`](#use-inline-field-description), [`--use-schema-description`](#use-schema-description)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input type_alias.json --use-type-alias --use-field-description # (1)!
    ```

    1. :material-arrow-left: `--use-field-description` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: "3.0.0"
        info:
          version: 1.0.0
          title: Swagger Petstore
          license:
            name: MIT
        servers:
          - url: http://petstore.swagger.io/v1
        paths:
          /pets:
            get:
              summary: List all pets
              operationId: listPets
              tags:
                - pets
              parameters:
                - name: limit
                  in: query
                  description: How many items to return at one time (max 100)
                  required: false
                  schema:
                    type: integer
                    format: int32
              responses:
                '200':
                  description: A paged array of pets
                  headers:
                    x-next:
                      description: A link to the next page of responses
                      schema:
                        type: string
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
            post:
              summary: Create a pet
              operationId: createPets
              tags:
                - pets
              responses:
                '201':
                  description: Null response
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
          /pets/{petId}:
            get:
              summary: Info for a specific pet
              operationId: showPetById
              tags:
                - pets
              parameters:
                - name: petId
                  in: path
                  required: true
                  description: The id of the pet to retrieve
                  schema:
                    type: string
              responses:
                '200':
                  description: Expected response to a valid request
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
            x-amazon-apigateway-integration:
              uri:
                Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
              passthroughBehavior: when_no_templates
              httpMethod: POST
              type: aws_proxy
        components:
          schemas:
            Pet:
              required:
                - id
                - name
              properties:
                id:
                  type: integer
                  format: int64
                  default: 1
                name:
                  type: string
                tag:
                  type: string
            Pets:
              type: array
              items:
                $ref: "#/components/schemas/Pet"
            Users:
              type: array
              items:
                required:
                  - id
                  - name
                properties:
                  id:
                    type: integer
                    format: int64
                  name:
                    type: string
                  tag:
                    type: string
            Id:
              type: string
            Rules:
              type: array
              items:
                type: string
            Error:
              description: "error result.\nNow with multi-line docstrings."
              required:
                - code
                - message
              properties:
                code:
                  type: integer
                  format: int32
                message:
                  type: string
            apis:
              type: array
              items:
                type: object
                properties:
                  apiKey:
                    type: string
                    description: "To be used as a dataset parameter value.\nNow also with multi-line docstrings."
                  apiVersionNumber:
                    type: string
                    description: To be used as a version parameter value
                  apiUrl:
                    type: string
                    format: uri
                    description: "The URL describing the dataset's fields"
                  apiDocumentationUrl:
                    type: string
                    format: uri
                    description: A URL to the API console for each API
            Event:
              type: object
              description: Event object
              properties:
                name:
                  type: string
            Result:
                type: object
                properties:
                  event:
                    $ref: '#/components/schemas/Event'
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  api_multiline_docstrings.yaml
        #   timestamp: 2022-11-11T00:00:00+00:00

        from __future__ import annotations

        from pydantic import AnyUrl, BaseModel, RootModel


        class Pet(BaseModel):
            id: int
            name: str
            tag: str | None = None


        class Pets(RootModel[list[Pet]]):
            root: list[Pet]


        class User(BaseModel):
            id: int
            name: str
            tag: str | None = None


        class Users(RootModel[list[User]]):
            root: list[User]


        class Id(RootModel[str]):
            root: str


        class Rules(RootModel[list[str]]):
            root: list[str]


        class Error(BaseModel):
            code: int
            message: str


        class Api(BaseModel):
            apiKey: str | None = None
            """
            To be used as a dataset parameter value.
            Now also with multi-line docstrings.
            """
            apiVersionNumber: str | None = None
            """
            To be used as a version parameter value
            """
            apiUrl: AnyUrl | None = None
            """
            The URL describing the dataset's fields
            """
            apiDocumentationUrl: AnyUrl | None = None
            """
            A URL to the API console for each API
            """


        class Apis(RootModel[list[Api]]):
            root: list[Api]


        class Event(BaseModel):
            name: str | None = None


        class Result(BaseModel):
            event: Event | None = None
        ```

        <!-- fmt: on -->

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "definitions": {
            "SimpleString": {
              "type": "string"
            },
            "UnionType": {
              "anyOf": [
                {"type": "string"},
                {"type": "integer"}
              ]
            },
            "ArrayType": {
              "type": "array",
              "items": {"type": "string"}
            },
            "AnnotatedType": {
              "title": "MyAnnotatedType",
              "description": "An annotated union type",
              "anyOf": [
                {"type": "string"},
                {"type": "boolean"}
              ]
            },
            "ModelWithTypeAliasField": {
              "type": "object",
              "properties": {
                "simple_field": {"$ref": "#/definitions/SimpleString"},
                "union_field": {"$ref": "#/definitions/UnionType"},
                "array_field": {"$ref": "#/definitions/ArrayType"},
                "annotated_field": {"$ref": "#/definitions/AnnotatedType"}
              }
            }
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  type_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Annotated, Any

        from pydantic import BaseModel, Field
        from typing_extensions import TypeAliasType

        Model = TypeAliasType("Model", Any)


        SimpleString = TypeAliasType("SimpleString", str)


        UnionType = TypeAliasType("UnionType", str | int)


        ArrayType = TypeAliasType("ArrayType", list[str])


        AnnotatedType = TypeAliasType(
            "AnnotatedType", Annotated[str | bool, Field(..., title='MyAnnotatedType')]
        )
        """
        An annotated union type
        """


        class ModelWithTypeAliasField(BaseModel):
            simple_field: SimpleString | None = None
            union_field: UnionType | None = None
            array_field: ArrayType | None = None
            annotated_field: AnnotatedType | None = None
        ```

        <!-- fmt: on -->

---

## `--use-field-description-example` {#use-field-description-example}

Add field examples to docstrings.

The `--use-field-description-example` flag adds the `example` or `examples`
property from schema fields as docstrings. This provides documentation that
is visible in IDE intellisense.

**Related:** [`--use-field-description`](#use-field-description), [`--use-inline-field-description`](#use-inline-field-description)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input extras.json --use-field-description-example # (1)!
    ```

    1. :material-arrow-left: `--use-field-description-example` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Extras",
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "normal key",
          "key1": 123,
          "key2": 456,
          "$exclude": 123,
          "invalid-key-1": "abc",
          "-invalid+key_2": "efg",
          "$comment": "comment",
          "$id": "#name",
          "register": "hij",
          "schema": "klm",
          "x-repr": true,
          "x-abc": true,
          "example": "example",
          "readOnly": true
        },
        "age": {
          "type": "integer",
          "example": 12,
          "writeOnly": true,
          "examples": [
            13,
            20
          ]
        },
        "status": {
          "type": "string",
          "examples": [
            "active"
          ]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  extras.json
    #   timestamp: 2022-11-11T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field


    class Extras(BaseModel):
        name: str | None = Field(None, description='normal key', examples=['example'])
        """
        Example: 'example'
        """
        age: int | None = Field(None, examples=[13, 20], json_schema_extra={'example': 12})
        """
        Examples:
        - 13
        - 20
        """
        status: str | None = Field(None, examples=['active'])
        """
        Example: 'active'
        """
    ```

    <!-- fmt: on -->

---

## `--use-inline-field-description` {#use-inline-field-description}

Add field descriptions as inline comments.

The `--use-inline-field-description` flag adds the `description` property from
schema fields as inline comments after each field definition. This provides
documentation without using Field() wrappers.

**Related:** [`--use-field-description`](#use-field-description), [`--use-schema-description`](#use-schema-description)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api_multiline_docstrings.yaml --use-inline-field-description # (1)!
    ```

    1. :material-arrow-left: `--use-inline-field-description` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: "3.0.0"
        info:
          version: 1.0.0
          title: Swagger Petstore
          license:
            name: MIT
        servers:
          - url: http://petstore.swagger.io/v1
        paths:
          /pets:
            get:
              summary: List all pets
              operationId: listPets
              tags:
                - pets
              parameters:
                - name: limit
                  in: query
                  description: How many items to return at one time (max 100)
                  required: false
                  schema:
                    type: integer
                    format: int32
              responses:
                '200':
                  description: A paged array of pets
                  headers:
                    x-next:
                      description: A link to the next page of responses
                      schema:
                        type: string
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
            post:
              summary: Create a pet
              operationId: createPets
              tags:
                - pets
              responses:
                '201':
                  description: Null response
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
          /pets/{petId}:
            get:
              summary: Info for a specific pet
              operationId: showPetById
              tags:
                - pets
              parameters:
                - name: petId
                  in: path
                  required: true
                  description: The id of the pet to retrieve
                  schema:
                    type: string
              responses:
                '200':
                  description: Expected response to a valid request
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
            x-amazon-apigateway-integration:
              uri:
                Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
              passthroughBehavior: when_no_templates
              httpMethod: POST
              type: aws_proxy
        components:
          schemas:
            Pet:
              required:
                - id
                - name
              properties:
                id:
                  type: integer
                  format: int64
                  default: 1
                name:
                  type: string
                tag:
                  type: string
            Pets:
              type: array
              items:
                $ref: "#/components/schemas/Pet"
            Users:
              type: array
              items:
                required:
                  - id
                  - name
                properties:
                  id:
                    type: integer
                    format: int64
                  name:
                    type: string
                  tag:
                    type: string
            Id:
              type: string
            Rules:
              type: array
              items:
                type: string
            Error:
              description: "error result.\nNow with multi-line docstrings."
              required:
                - code
                - message
              properties:
                code:
                  type: integer
                  format: int32
                message:
                  type: string
            apis:
              type: array
              items:
                type: object
                properties:
                  apiKey:
                    type: string
                    description: "To be used as a dataset parameter value.\nNow also with multi-line docstrings."
                  apiVersionNumber:
                    type: string
                    description: To be used as a version parameter value
                  apiUrl:
                    type: string
                    format: uri
                    description: "The URL describing the dataset's fields"
                  apiDocumentationUrl:
                    type: string
                    format: uri
                    description: A URL to the API console for each API
            Event:
              type: object
              description: Event object
              properties:
                name:
                  type: string
            Result:
                type: object
                properties:
                  event:
                    $ref: '#/components/schemas/Event'
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  api_multiline_docstrings.yaml
        #   timestamp: 2022-11-11T00:00:00+00:00

        from __future__ import annotations

        from pydantic import AnyUrl, BaseModel, Field, RootModel


        class Pet(BaseModel):
            id: int
            name: str
            tag: str | None = None


        class Pets(RootModel[list[Pet]]):
            root: list[Pet]


        class User(BaseModel):
            id: int
            name: str
            tag: str | None = None


        class Users(RootModel[list[User]]):
            root: list[User]


        class Id(RootModel[str]):
            root: str


        class Rules(RootModel[list[str]]):
            root: list[str]


        class Error(BaseModel):
            code: int
            message: str


        class Api(BaseModel):
            apiKey: str | None = Field(
                None,
                description='To be used as a dataset parameter value.\nNow also with multi-line docstrings.',
            )
            """
            To be used as a dataset parameter value.
            Now also with multi-line docstrings.
            """

            apiVersionNumber: str | None = Field(
                None, description='To be used as a version parameter value'
            )
            """To be used as a version parameter value"""

            apiUrl: AnyUrl | None = Field(
                None, description="The URL describing the dataset's fields"
            )
            """The URL describing the dataset's fields"""

            apiDocumentationUrl: AnyUrl | None = Field(
                None, description='A URL to the API console for each API'
            )
            """A URL to the API console for each API"""


        class Apis(RootModel[list[Api]]):
            root: list[Api]


        class Event(BaseModel):
            name: str | None = None


        class Result(BaseModel):
            event: Event | None = None
        ```

        <!-- fmt: on -->

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "title": "MultilineDescriptionWithExample",
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "description": "User name.\nThis is a multi-line description.",
              "example": "John Doe"
            }
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  multiline_description_with_example.json
        #   timestamp: 2022-11-11T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class MultilineDescriptionWithExample(BaseModel):
            name: str | None = Field(
                None,
                description='User name.\nThis is a multi-line description.',
                examples=['John Doe'],
            )
            """
            User name.
            This is a multi-line description.

            Example: 'John Doe'
            """
        ```

        <!-- fmt: on -->

---

## `--use-schema-description` {#use-schema-description}

Use schema description as class docstring.

The `--use-schema-description` flag extracts the `description` property from
schema definitions and adds it as a docstring to the generated class. This is
useful for preserving documentation from your schema in the generated code.

**Related:** [`--use-field-description`](#use-field-description), [`--use-inline-field-description`](#use-inline-field-description)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api_multiline_docstrings.yaml --use-schema-description # (1)!
    ```

    1. :material-arrow-left: `--use-schema-description` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: "error result.\nNow with multi-line docstrings."
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: "To be used as a dataset parameter value.\nNow also with multi-line docstrings."
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api_multiline_docstrings.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        """
        error result.
        Now with multi-line docstrings.
        """

        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None,
            description='To be used as a dataset parameter value.\nNow also with multi-line docstrings.',
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        """
        Event object
        """

        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--use-serialization-alias` {#use-serialization-alias}

Use serialization_alias instead of alias for field aliasing (Pydantic v2 only).

The `--use-serialization-alias` flag changes field aliasing to use `serialization_alias`
instead of `alias`. This allows setting values using the Pythonic field name while
serializing to the original JSON property name.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input no_alias.json --use-serialization-alias --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--use-serialization-alias` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "first-name": {
          "type": "string"
        },
        "last-name": {
          "type": "string"
        },
        "email_address": {
          "type": "string"
        }
      },
      "required": ["first-name", "last-name"]
    }
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  no_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Person(BaseModel):
            first_name: str = Field(..., serialization_alias='first-name')
            last_name: str = Field(..., serialization_alias='last-name')
            email_address: str | None = None
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  no_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Person(BaseModel):
            first_name: str = Field(..., alias='first-name')
            last_name: str = Field(..., alias='last-name')
            email_address: str | None = None
        ```

        <!-- fmt: on -->

---

## `--use-single-line-docstring` {#use-single-line-docstring}

Emit short docstrings on a single line.

The `--use-single-line-docstring` flag formats docstrings that fit on one line
as compact single-line docstrings while keeping the historical multi-line
format as the default.

**Related:** [`--use-field-description`](#use-field-description), [`--use-schema-description`](#use-schema-description)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --use-field-description --use-single-line-docstring # (1)!
    ```

    1. :material-arrow-left: `--use-single-line-docstring` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": ["string", "null"],
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  person.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, Field, conint


    class Person(BaseModel):
        firstName: str | None = None
        """The person's first name."""
        lastName: str | None = None
        """The person's last name."""
        age: conint(ge=0) | None = None
        """Age in years which must be equal to or greater than zero."""
        friends: list[Any] | None = None
        comment: None = Field(None)
    ```

    <!-- fmt: on -->

---

## `--use-title-as-name` {#use-title-as-name}

Use schema title as the generated class name.

The `--use-title-as-name` flag uses the `title` property from the schema
as the class name instead of deriving it from the property name or path.
This is useful when schemas have descriptive titles that should be preserved.

**Related:** [`--class-name`](model-customization.md#class-name)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input titles.json --use-title-as-name # (1)!
    ```

    1. :material-arrow-left: `--use-title-as-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "ProcessingStatus": {
          "title": "Processing Status Title",
          "enum": [
            "COMPLETED",
            "PENDING",
            "FAILED"
          ],
          "type": "string",
          "description": "The processing status"
        },
        "kind": {
          "type": "string"
        },
        "ExtendedProcessingTask": {
          "title": "Extended Processing Task Title",
          "oneOf": [
            {
              "$ref": "#"
            },
            {
              "type": "object",
              "title": "NestedCommentTitle",
              "properties": {
                "comment": {
                  "type": "string"
                }
              }
            }
          ]
        },
        "ExtendedProcessingTasks": {
          "title": "Extended Processing Tasks Title",
          "type": "array",
          "items": [
            {
              "$ref": "#/definitions/ExtendedProcessingTask"
            }
          ]
        },
        "ProcessingTask": {
          "title": "Processing Task Title",
          "type": "object",
          "properties": {
            "processing_status_union": {
              "title": "Processing Status Union Title",
              "oneOf": [
                {
                  "title": "Processing Status Detail",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "description": {
                      "type": "string"
                    }
                  }
                },
                {
                  "$ref": "#/definitions/ExtendedProcessingTask"
                },
                {
                  "$ref": "#/definitions/ProcessingStatus"
                }
              ],
              "default": "COMPLETED"
            },
            "processing_status": {
              "$ref": "#/definitions/ProcessingStatus",
              "default": "COMPLETED"
            },
            "name": {
              "type": "string"
            },
            "kind": {
              "$ref": "#/definitions/kind"
            }
          }
        }
      },
      "title": "Processing Tasks Title",
      "type": "array",
          "items": [
            {
              "$ref": "#/definitions/ProcessingTask"
            }
          ]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  titles.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel, Field, RootModel


    class ProcessingStatusTitle(Enum):
        COMPLETED = 'COMPLETED'
        PENDING = 'PENDING'
        FAILED = 'FAILED'


    class Kind(RootModel[str]):
        root: str


    class NestedCommentTitle(BaseModel):
        comment: str | None = None


    class ProcessingStatusDetail(BaseModel):
        id: int | None = None
        description: str | None = None


    class ProcessingTaskTitle(BaseModel):
        processing_status_union: ProcessingStatusUnionTitle | None = Field(
            'COMPLETED', title='Processing Status Union Title', validate_default=True
        )
        processing_status: ProcessingStatusTitle | None = 'COMPLETED'
        name: str | None = None
        kind: Kind | None = None


    class ProcessingTasksTitle(RootModel[list[ProcessingTaskTitle]]):
        root: list[ProcessingTaskTitle] = Field(..., title='Processing Tasks Title')


    class ExtendedProcessingTask(RootModel[ProcessingTasksTitle | NestedCommentTitle]):
        root: ProcessingTasksTitle | NestedCommentTitle = Field(
            ..., title='Extended Processing Task Title'
        )


    class ExtendedProcessingTasksTitle(RootModel[list[ExtendedProcessingTask]]):
        root: list[ExtendedProcessingTask] = Field(
            ..., title='Extended Processing Tasks Title'
        )


    class ProcessingStatusUnionTitle(
        RootModel[ProcessingStatusDetail | ExtendedProcessingTask | ProcessingStatusTitle]
    ):
        root: ProcessingStatusDetail | ExtendedProcessingTask | ProcessingStatusTitle = (
            Field('COMPLETED', title='Processing Status Union Title', validate_default=True)
        )


    ProcessingTaskTitle.model_rebuild()
    ```

    <!-- fmt: on -->

---

---

# Typing Customization

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/typing-customization/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--allof-class-hierarchy`](#allof-class-hierarchy) | Controls how allOf schemas are represented in the generated ... |
| [`--allof-merge-mode`](#allof-merge-mode) | Merge constraints from root model references in allOf schema... |
| [`--disable-future-imports`](#disable-future-imports) | Prevent automatic addition of __future__ imports in generate... |
| [`--enum-field-as-literal`](#enum-field-as-literal) | Convert all enum fields to Literal types instead of Enum cla... |
| [`--enum-field-as-literal-map`](#enum-field-as-literal-map) | Override enum/literal generation per-field via JSON mapping. |
| [`--ignore-enum-constraints`](#ignore-enum-constraints) | Ignore enum constraints and use base string type instead of ... |
| [`--import-overrides`](#import-overrides) | Override modules for generated imports by symbol name. |
| [`--no-use-closed-typed-dict`](#no-use-closed-typed-dict) | Disable PEP 728 TypedDict closed/extra_items generation. |
| [`--no-use-specialized-enum`](#no-use-specialized-enum) | Disable specialized Enum classes for Python 3.11+ code gener... |
| [`--no-use-standard-collections`](#no-use-standard-collections) | Use typing.Dict/List instead of built-in dict/list for conta... |
| [`--no-use-union-operator`](#no-use-union-operator) | Use Union[X, Y] / Optional[X] instead of X | Y union operato... |
| [`--output-date-class`](#output-date-class) | Specify date class type for date schema fields. |
| [`--output-datetime-class`](#output-datetime-class) | Specify datetime class type for date-time schema fields. |
| [`--strict-types`](#strict-types) | Enable strict type validation for specified Python types. |
| [`--type-mappings`](#type-mappings) | Override default type mappings for schema formats. |
| [`--type-overrides`](#type-overrides) | Replace schema model types with custom Python types via JSON... |
| [`--use-annotated`](#use-annotated) | Use typing.Annotated for Field() with constraints. |
| [`--use-closed-typed-dict`](#use-closed-typed-dict) | Generate TypedDict with PEP 728 closed/extra_items (default:... |
| [`--use-decimal-for-multiple-of`](#use-decimal-for-multiple-of) | Generate Decimal types for fields with multipleOf constraint... |
| [`--use-generic-container-types`](#use-generic-container-types) | Use generic container types (Sequence, Mapping) for type hin... |
| [`--use-non-positive-negative-number-constrained-types`](#use-non-positive-negative-number-constrained-types) | Use NonPositive/NonNegative types for number constraints. |
| [`--use-object-type`](#use-object-type) | Use object instead of Any for unspecified object and array v... |
| [`--use-pendulum`](#use-pendulum) | Use pendulum types for date, time, and duration fields. |
| [`--use-root-model-type-alias`](#use-root-model-type-alias) | Generate RootModel as type alias format for better mypy supp... |
| [`--use-specialized-enum`](#use-specialized-enum) | Generate StrEnum/IntEnum for string/integer enums (Python 3.... |
| [`--use-standard-collections`](#use-standard-collections) | Use built-in dict/list instead of typing.Dict/List. |
| [`--use-standard-primitive-types`](#use-standard-primitive-types) | Use Python standard library types for string formats instead... |
| [`--use-total-false-for-typed-dict`](#use-total-false-for-typed-dict) | Generate TypedDict declarations with `total=False`. |
| [`--use-tuple-for-fixed-items`](#use-tuple-for-fixed-items) | Generate tuple types for arrays with items array syntax. |
| [`--use-tuple-for-fixed-length-arrays`](#use-tuple-for-fixed-length-arrays) | Generate tuple types for homogeneous fixed-length arrays. |
| [`--use-type-alias`](#use-type-alias) | Use TypeAlias instead of root models for type definitions (e... |
| [`--use-type-alias-type`](#use-type-alias-type) | Use runtime TypeAliasType objects for aliases before Python ... |
| [`--use-typed-nullable-map-values`](#use-typed-nullable-map-values) | Type the values of nullable maps as their schemas say instea... |
| [`--use-union-operator`](#use-union-operator) | Use | operator for Union types (PEP 604). |
| [`--use-unique-items-as-set`](#use-unique-items-as-set) | Generate set types for arrays with uniqueItems constraint. |

---

## 🍳 Recipes

### Use modern Python annotations

Target a recent Python version and prefer built-in collection and union syntax in generated types.

**Options:** [`--target-python-version`](model-customization.md#target-python-version), [`--use-union-operator`](#use-union-operator), [`--use-standard-collections`](#use-standard-collections)

### Keep validation constraints in type hints

Combine Annotated hints with strict scalar handling when downstream tooling reads type metadata.

**Options:** [`--use-annotated`](#use-annotated), [`--field-constraints`](field-customization.md#field-constraints), [`--strict-types`](#strict-types)

---

## `--allof-class-hierarchy` {#allof-class-hierarchy}

Controls how allOf schemas are represented in the generated class hierarchy.
`--allof-class-hierarchy if-no-conflict` (default) creates parent classes for allOf schemas
only when there are no property conflicts between parent schemas. Otherwise, properties are merged into the child class
which is then decoupled from the parent classes and no longer inherits from them.
`--allof-class-hierarchy always` keeps class hierarchy for allOf schemas,
even in multiple inheritance scenarios where two parent schemas define the same property.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input allof_root_model_constraints.json --allof-class-hierarchy always # (1)!
    ```

    1. :material-arrow-left: `--allof-class-hierarchy` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "StringDatatype": {
          "description": "A base string type.",
          "type": "string",
          "pattern": "^\\S(.*\\S)?$"
        },
        "ConstrainedStringDatatype": {
          "description": "A constrained string.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" },
            { "type": "string", "minLength": 1, "pattern": "^[A-Z].*" }
          ]
        },
        "IntegerDatatype": {
          "description": "A whole number.",
          "type": "integer"
        },
        "NonNegativeIntegerDatatype": {
          "description": "Non-negative integer.",
          "allOf": [
            { "$ref": "#/definitions/IntegerDatatype" },
            { "minimum": 0 }
          ]
        },
        "BoundedIntegerDatatype": {
          "description": "Integer between 0 and 100.",
          "allOf": [
            { "$ref": "#/definitions/IntegerDatatype" },
            { "minimum": 0, "maximum": 100 }
          ]
        },
        "EmailDatatype": {
          "description": "Email with format.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" },
            { "format": "email" }
          ]
        },
        "FormattedStringDatatype": {
          "description": "A string with email format.",
          "type": "string",
          "format": "email"
        },
        "ObjectBase": {
          "type": "object",
          "properties": {
            "id": { "type": "integer" }
          }
        },
        "ObjectWithAllOf": {
          "description": "Object inheritance - not a root model.",
          "allOf": [
            { "$ref": "#/definitions/ObjectBase" },
            { "type": "object", "properties": { "name": { "type": "string" } } }
          ]
        },
        "MultiRefAllOf": {
          "description": "Multiple refs - not handled by new code.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" },
            { "$ref": "#/definitions/IntegerDatatype" }
          ]
        },
        "NoConstraintAllOf": {
          "description": "No constraints added.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" }
          ]
        },
        "IncompatibleTypeAllOf": {
          "description": "Incompatible types.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" },
            { "type": "boolean" }
          ]
        },
        "ConstraintWithProperties": {
          "description": "Constraint item has properties.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" },
            { "properties": { "extra": { "type": "string" } } }
          ]
        },
        "ConstraintWithItems": {
          "description": "Constraint item has items.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" },
            { "items": { "type": "string" } }
          ]
        },
        "NumberIntegerCompatible": {
          "description": "Number and integer are compatible.",
          "allOf": [
            { "$ref": "#/definitions/IntegerDatatype" },
            { "type": "number", "minimum": 0 }
          ]
        },
        "RefWithSchemaKeywords": {
          "description": "Ref with additional schema keywords.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype", "minLength": 5 },
            { "maxLength": 100 }
          ]
        },
        "ArrayDatatype": {
          "type": "array",
          "items": { "type": "string" }
        },
        "RefToArrayAllOf": {
          "description": "Ref to array - not a root model.",
          "allOf": [
            { "$ref": "#/definitions/ArrayDatatype" },
            { "minItems": 1 }
          ]
        },
        "ObjectNoPropsDatatype": {
          "type": "object"
        },
        "RefToObjectNoPropsAllOf": {
          "description": "Ref to object without properties - not a root model.",
          "allOf": [
            { "$ref": "#/definitions/ObjectNoPropsDatatype" },
            { "minProperties": 1 }
          ]
        },
        "PatternPropsDatatype": {
          "patternProperties": {
            "^S_": { "type": "string" }
          }
        },
        "RefToPatternPropsAllOf": {
          "description": "Ref to patternProperties - not a root model.",
          "allOf": [
            { "$ref": "#/definitions/PatternPropsDatatype" },
            { "minProperties": 1 }
          ]
        },
        "NestedAllOfDatatype": {
          "allOf": [
            { "type": "string" },
            { "minLength": 1 }
          ]
        },
        "RefToNestedAllOfAllOf": {
          "description": "Ref to nested allOf root model.",
          "allOf": [
            { "$ref": "#/definitions/NestedAllOfDatatype" },
            { "maxLength": 100 }
          ]
        },
        "ConstraintsOnlyDatatype": {
          "description": "Constraints only, no type.",
          "minLength": 1,
          "pattern": "^[A-Z]"
        },
        "RefToConstraintsOnlyAllOf": {
          "description": "Ref to constraints-only schema.",
          "allOf": [
            { "$ref": "#/definitions/ConstraintsOnlyDatatype" },
            { "maxLength": 100 }
          ]
        },
        "NoDescriptionAllOf": {
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" },
            { "minLength": 5 }
          ]
        },
        "EmptyConstraintItemAllOf": {
          "description": "AllOf with empty constraint item.",
          "allOf": [
            { "$ref": "#/definitions/StringDatatype" },
            {},
            { "maxLength": 50 }
          ]
        },
        "ConflictingFormatAllOf": {
          "description": "Conflicting formats - falls back to existing behavior.",
          "allOf": [
            { "$ref": "#/definitions/FormattedStringDatatype" },
            { "format": "date-time" }
          ]
        }
      },
      "type": "object",
      "properties": {
        "name": { "$ref": "#/definitions/ConstrainedStringDatatype" },
        "count": { "$ref": "#/definitions/NonNegativeIntegerDatatype" },
        "percentage": { "$ref": "#/definitions/BoundedIntegerDatatype" },
        "email": { "$ref": "#/definitions/EmailDatatype" },
        "obj": { "$ref": "#/definitions/ObjectWithAllOf" },
        "multi": { "$ref": "#/definitions/MultiRefAllOf" },
        "noconstraint": { "$ref": "#/definitions/NoConstraintAllOf" },
        "incompatible": { "$ref": "#/definitions/IncompatibleTypeAllOf" },
        "withprops": { "$ref": "#/definitions/ConstraintWithProperties" },
        "withitems": { "$ref": "#/definitions/ConstraintWithItems" },
        "numint": { "$ref": "#/definitions/NumberIntegerCompatible" },
        "refwithkw": { "$ref": "#/definitions/RefWithSchemaKeywords" },
        "refarr": { "$ref": "#/definitions/RefToArrayAllOf" },
        "refobjnoprops": { "$ref": "#/definitions/RefToObjectNoPropsAllOf" },
        "refpatternprops": { "$ref": "#/definitions/RefToPatternPropsAllOf" },
        "refnestedallof": { "$ref": "#/definitions/RefToNestedAllOfAllOf" },
        "refconstraintsonly": { "$ref": "#/definitions/RefToConstraintsOnlyAllOf" },
        "nodescription": { "$ref": "#/definitions/NoDescriptionAllOf" },
        "emptyconstraint": { "$ref": "#/definitions/EmptyConstraintItemAllOf" },
        "conflictingformat": { "$ref": "#/definitions/ConflictingFormatAllOf" }
      }
    }
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  allof_class_hierarchy.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field, constr


        class Entity(BaseModel):
            type: str
            type_list: list[str] | None = ['playground:Entity']


        class Entity2(BaseModel):
            type: str
            type_list: list[str]


        class Thing(Entity):
            type: str
            type_list: list[str] | None = ['playground:Thing']
            name: constr(min_length=1) = Field(..., description='The things name')


        class Location(Entity2):
            type: str
            type_list: list[str]
            address: constr(min_length=5) = Field(
                ..., description='The address of the location'
            )


        class Person(Thing, Location):
            name: constr(min_length=1) = Field(..., description="The person's name")
            type: str
            type_list: list[str]
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  allof_class_hierarchy.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Any

        from pydantic import BaseModel, Field, constr


        class Person(BaseModel):
            name: constr(min_length=1) = Field(..., description='The things name')
            type: Any | None = 'playground:Location'
            type_list: list[Any] | None = [
                'playground:Person',
                'playground:Thing',
                'playground:Location',
            ]
            address: constr(min_length=5) = Field(
                ..., description='The address of the location'
            )


        class Entity(BaseModel):
            type: str
            type_list: list[str] | None = ['playground:Entity']


        class Entity2(BaseModel):
            type: str
            type_list: list[str]


        class Thing(Entity):
            type: str | None = 'playground:Thing'
            type_list: list[str] | None = ['playground:Thing']
            name: constr(min_length=1) = Field(..., description='The things name')


        class Location(Entity2):
            type: str | None = 'playground:Location'
            type_list: list[str] | None = ['playground:Location']
            address: constr(min_length=5) = Field(
                ..., description='The address of the location'
            )
        ```

        <!-- fmt: on -->

---

## `--allof-merge-mode` {#allof-merge-mode}

Merge constraints from root model references in allOf schemas.

The `--allof-merge-mode constraints` merges only constraint properties
(minLength, maximum, etc.) from parent schemas referenced in allOf.
This ensures child schemas inherit validation constraints while keeping
other properties separate.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input allof_root_model_constraints.json --allof-merge-mode constraints # (1)!
    ```

    1. :material-arrow-left: `--allof-merge-mode` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: "3.0.0"
        info:
          title: Test materialize allOf defaults
          version: "1.0.0"
        components:
          schemas:
            Parent:
              type: object
              properties:
                name:
                  type: string
                  default: "parent_default"
                  minLength: 1
                count:
                  type: integer
                  default: 10
                  minimum: 0
            Child:
              allOf:
                - $ref: "#/components/schemas/Parent"
                - type: object
                  properties:
                    name:
                      maxLength: 100
                    count:
                      maximum: 1000
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  allof_materialize_defaults.yaml
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, conint, constr


        class Parent(BaseModel):
            name: constr(min_length=1) | None = 'parent_default'
            count: conint(ge=0) | None = 10


        class Child(Parent):
            name: constr(min_length=1, max_length=100) | None = 'parent_default'
            count: conint(ge=0, le=1000) | None = 10
        ```

        <!-- fmt: on -->

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "definitions": {
            "StringDatatype": {
              "description": "A base string type.",
              "type": "string",
              "pattern": "^\\S(.*\\S)?$"
            },
            "ConstrainedStringDatatype": {
              "description": "A constrained string.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" },
                { "type": "string", "minLength": 1, "pattern": "^[A-Z].*" }
              ]
            },
            "IntegerDatatype": {
              "description": "A whole number.",
              "type": "integer"
            },
            "NonNegativeIntegerDatatype": {
              "description": "Non-negative integer.",
              "allOf": [
                { "$ref": "#/definitions/IntegerDatatype" },
                { "minimum": 0 }
              ]
            },
            "BoundedIntegerDatatype": {
              "description": "Integer between 0 and 100.",
              "allOf": [
                { "$ref": "#/definitions/IntegerDatatype" },
                { "minimum": 0, "maximum": 100 }
              ]
            },
            "EmailDatatype": {
              "description": "Email with format.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" },
                { "format": "email" }
              ]
            },
            "FormattedStringDatatype": {
              "description": "A string with email format.",
              "type": "string",
              "format": "email"
            },
            "ObjectBase": {
              "type": "object",
              "properties": {
                "id": { "type": "integer" }
              }
            },
            "ObjectWithAllOf": {
              "description": "Object inheritance - not a root model.",
              "allOf": [
                { "$ref": "#/definitions/ObjectBase" },
                { "type": "object", "properties": { "name": { "type": "string" } } }
              ]
            },
            "MultiRefAllOf": {
              "description": "Multiple refs - not handled by new code.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" },
                { "$ref": "#/definitions/IntegerDatatype" }
              ]
            },
            "NoConstraintAllOf": {
              "description": "No constraints added.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" }
              ]
            },
            "IncompatibleTypeAllOf": {
              "description": "Incompatible types.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" },
                { "type": "boolean" }
              ]
            },
            "ConstraintWithProperties": {
              "description": "Constraint item has properties.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" },
                { "properties": { "extra": { "type": "string" } } }
              ]
            },
            "ConstraintWithItems": {
              "description": "Constraint item has items.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" },
                { "items": { "type": "string" } }
              ]
            },
            "NumberIntegerCompatible": {
              "description": "Number and integer are compatible.",
              "allOf": [
                { "$ref": "#/definitions/IntegerDatatype" },
                { "type": "number", "minimum": 0 }
              ]
            },
            "RefWithSchemaKeywords": {
              "description": "Ref with additional schema keywords.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype", "minLength": 5 },
                { "maxLength": 100 }
              ]
            },
            "ArrayDatatype": {
              "type": "array",
              "items": { "type": "string" }
            },
            "RefToArrayAllOf": {
              "description": "Ref to array - not a root model.",
              "allOf": [
                { "$ref": "#/definitions/ArrayDatatype" },
                { "minItems": 1 }
              ]
            },
            "ObjectNoPropsDatatype": {
              "type": "object"
            },
            "RefToObjectNoPropsAllOf": {
              "description": "Ref to object without properties - not a root model.",
              "allOf": [
                { "$ref": "#/definitions/ObjectNoPropsDatatype" },
                { "minProperties": 1 }
              ]
            },
            "PatternPropsDatatype": {
              "patternProperties": {
                "^S_": { "type": "string" }
              }
            },
            "RefToPatternPropsAllOf": {
              "description": "Ref to patternProperties - not a root model.",
              "allOf": [
                { "$ref": "#/definitions/PatternPropsDatatype" },
                { "minProperties": 1 }
              ]
            },
            "NestedAllOfDatatype": {
              "allOf": [
                { "type": "string" },
                { "minLength": 1 }
              ]
            },
            "RefToNestedAllOfAllOf": {
              "description": "Ref to nested allOf root model.",
              "allOf": [
                { "$ref": "#/definitions/NestedAllOfDatatype" },
                { "maxLength": 100 }
              ]
            },
            "ConstraintsOnlyDatatype": {
              "description": "Constraints only, no type.",
              "minLength": 1,
              "pattern": "^[A-Z]"
            },
            "RefToConstraintsOnlyAllOf": {
              "description": "Ref to constraints-only schema.",
              "allOf": [
                { "$ref": "#/definitions/ConstraintsOnlyDatatype" },
                { "maxLength": 100 }
              ]
            },
            "NoDescriptionAllOf": {
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" },
                { "minLength": 5 }
              ]
            },
            "EmptyConstraintItemAllOf": {
              "description": "AllOf with empty constraint item.",
              "allOf": [
                { "$ref": "#/definitions/StringDatatype" },
                {},
                { "maxLength": 50 }
              ]
            },
            "ConflictingFormatAllOf": {
              "description": "Conflicting formats - falls back to existing behavior.",
              "allOf": [
                { "$ref": "#/definitions/FormattedStringDatatype" },
                { "format": "date-time" }
              ]
            }
          },
          "type": "object",
          "properties": {
            "name": { "$ref": "#/definitions/ConstrainedStringDatatype" },
            "count": { "$ref": "#/definitions/NonNegativeIntegerDatatype" },
            "percentage": { "$ref": "#/definitions/BoundedIntegerDatatype" },
            "email": { "$ref": "#/definitions/EmailDatatype" },
            "obj": { "$ref": "#/definitions/ObjectWithAllOf" },
            "multi": { "$ref": "#/definitions/MultiRefAllOf" },
            "noconstraint": { "$ref": "#/definitions/NoConstraintAllOf" },
            "incompatible": { "$ref": "#/definitions/IncompatibleTypeAllOf" },
            "withprops": { "$ref": "#/definitions/ConstraintWithProperties" },
            "withitems": { "$ref": "#/definitions/ConstraintWithItems" },
            "numint": { "$ref": "#/definitions/NumberIntegerCompatible" },
            "refwithkw": { "$ref": "#/definitions/RefWithSchemaKeywords" },
            "refarr": { "$ref": "#/definitions/RefToArrayAllOf" },
            "refobjnoprops": { "$ref": "#/definitions/RefToObjectNoPropsAllOf" },
            "refpatternprops": { "$ref": "#/definitions/RefToPatternPropsAllOf" },
            "refnestedallof": { "$ref": "#/definitions/RefToNestedAllOfAllOf" },
            "refconstraintsonly": { "$ref": "#/definitions/RefToConstraintsOnlyAllOf" },
            "nodescription": { "$ref": "#/definitions/NoDescriptionAllOf" },
            "emptyconstraint": { "$ref": "#/definitions/EmptyConstraintItemAllOf" },
            "conflictingformat": { "$ref": "#/definitions/ConflictingFormatAllOf" }
          }
        }
        ```

        **Output:**

        === "With Option"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  allof_root_model_constraints.json
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Any

            from pydantic import BaseModel, ConfigDict, EmailStr, Field, RootModel, conint, constr


            class StringDatatype(RootModel[constr(pattern=r'^\S(.*\S)?$')]):
                root: constr(pattern=r'^\S(.*\S)?$') = Field(..., description='A base string type.')


            class ConstrainedStringDatatype(RootModel[str]):
                model_config = ConfigDict(
                    regex_engine="python-re",
                )
                root: constr(pattern=r'(?=^\S(.*\S)?$)(?=^[A-Z].*)', min_length=1) = Field(
                    ..., description='A constrained string.'
                )


            class IntegerDatatype(RootModel[int]):
                root: int = Field(..., description='A whole number.')


            class NonNegativeIntegerDatatype(RootModel[conint(ge=0)]):
                root: conint(ge=0) = Field(..., description='Non-negative integer.')


            class BoundedIntegerDatatype(RootModel[conint(ge=0, le=100)]):
                root: conint(ge=0, le=100) = Field(..., description='Integer between 0 and 100.')


            class EmailDatatype(RootModel[EmailStr]):
                root: EmailStr = Field(..., description='Email with format.')


            class FormattedStringDatatype(RootModel[EmailStr]):
                root: EmailStr = Field(..., description='A string with email format.')


            class ObjectBase(BaseModel):
                id: int | None = None


            class ObjectWithAllOf(ObjectBase):
                name: str | None = None


            class MultiRefAllOf(BaseModel):
                pass


            class NoConstraintAllOf(RootModel[StringDatatype]):
                root: StringDatatype = Field(..., description='No constraints added.')


            class IncompatibleTypeAllOf(BaseModel):
                pass


            class ConstraintWithProperties(BaseModel):
                extra: str | None = None


            class ConstraintWithItems(BaseModel):
                pass


            class NumberIntegerCompatible(RootModel[conint(ge=0)]):
                root: conint(ge=0) = Field(..., description='Number and integer are compatible.')


            class RefWithSchemaKeywords(
                RootModel[constr(pattern=r'^\S(.*\S)?$', min_length=5, max_length=100)]
            ):
                root: constr(pattern=r'^\S(.*\S)?$', min_length=5, max_length=100) = Field(
                    ..., description='Ref with additional schema keywords.'
                )


            class ArrayDatatype(RootModel[list[str]]):
                root: list[str]


            class RefToArrayAllOf(BaseModel):
                pass


            class ObjectNoPropsDatatype(BaseModel):
                pass


            class RefToObjectNoPropsAllOf(ObjectNoPropsDatatype):
                pass


            class PatternPropsDatatype(RootModel[dict[constr(pattern=r'^S_'), str]]):
                root: dict[constr(pattern=r'^S_'), str]


            class RefToPatternPropsAllOf(BaseModel):
                pass


            class NestedAllOfDatatype(RootModel[constr(min_length=1)]):
                root: constr(min_length=1)


            class RefToNestedAllOfAllOf(RootModel[constr(min_length=1, max_length=100)]):
                root: constr(min_length=1, max_length=100) = Field(
                    ..., description='Ref to nested allOf root model.'
                )


            class ConstraintsOnlyDatatype(RootModel[Any]):
                root: Any = Field(..., description='Constraints only, no type.')


            class RefToConstraintsOnlyAllOf(RootModel[Any]):
                root: Any = Field(..., description='Ref to constraints-only schema.')


            class NoDescriptionAllOf(RootModel[constr(pattern=r'^\S(.*\S)?$', min_length=5)]):
                root: constr(pattern=r'^\S(.*\S)?$', min_length=5) = Field(
                    ..., description='A base string type.'
                )


            class EmptyConstraintItemAllOf(
                RootModel[constr(pattern=r'^\S(.*\S)?$', max_length=50)]
            ):
                root: constr(pattern=r'^\S(.*\S)?$', max_length=50) = Field(
                    ..., description='AllOf with empty constraint item.'
                )


            class ConflictingFormatAllOf(BaseModel):
                pass


            class Model(BaseModel):
                name: ConstrainedStringDatatype | None = None
                count: NonNegativeIntegerDatatype | None = None
                percentage: BoundedIntegerDatatype | None = None
                email: EmailDatatype | None = None
                obj: ObjectWithAllOf | None = None
                multi: MultiRefAllOf | None = None
                noconstraint: NoConstraintAllOf | None = None
                incompatible: IncompatibleTypeAllOf | None = None
                withprops: ConstraintWithProperties | None = None
                withitems: ConstraintWithItems | None = None
                numint: NumberIntegerCompatible | None = None
                refwithkw: RefWithSchemaKeywords | None = None
                refarr: RefToArrayAllOf | None = None
                refobjnoprops: RefToObjectNoPropsAllOf | None = None
                refpatternprops: RefToPatternPropsAllOf | None = None
                refnestedallof: RefToNestedAllOfAllOf | None = None
                refconstraintsonly: RefToConstraintsOnlyAllOf | None = None
                nodescription: NoDescriptionAllOf | None = None
                emptyconstraint: EmptyConstraintItemAllOf | None = None
                conflictingformat: ConflictingFormatAllOf | None = None
            ```

            <!-- fmt: on -->

        === "Without Option"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  allof_root_model_constraints.json
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Any

            from pydantic import BaseModel, EmailStr, Field, RootModel, conint, constr


            class StringDatatype(RootModel[constr(pattern=r'^\S(.*\S)?$')]):
                root: constr(pattern=r'^\S(.*\S)?$') = Field(..., description='A base string type.')


            class ConstrainedStringDatatype(RootModel[constr(pattern=r'^[A-Z].*', min_length=1)]):
                root: constr(pattern=r'^[A-Z].*', min_length=1) = Field(
                    ..., description='A constrained string.'
                )


            class IntegerDatatype(RootModel[int]):
                root: int = Field(..., description='A whole number.')


            class NonNegativeIntegerDatatype(RootModel[conint(ge=0)]):
                root: conint(ge=0) = Field(..., description='Non-negative integer.')


            class BoundedIntegerDatatype(RootModel[conint(ge=0, le=100)]):
                root: conint(ge=0, le=100) = Field(..., description='Integer between 0 and 100.')


            class EmailDatatype(RootModel[EmailStr]):
                root: EmailStr = Field(..., description='Email with format.')


            class FormattedStringDatatype(RootModel[EmailStr]):
                root: EmailStr = Field(..., description='A string with email format.')


            class ObjectBase(BaseModel):
                id: int | None = None


            class ObjectWithAllOf(ObjectBase):
                name: str | None = None


            class MultiRefAllOf(BaseModel):
                pass


            class NoConstraintAllOf(RootModel[StringDatatype]):
                root: StringDatatype = Field(..., description='No constraints added.')


            class IncompatibleTypeAllOf(BaseModel):
                pass


            class ConstraintWithProperties(BaseModel):
                extra: str | None = None


            class ConstraintWithItems(BaseModel):
                pass


            class NumberIntegerCompatible(RootModel[conint(ge=0)]):
                root: conint(ge=0) = Field(..., description='Number and integer are compatible.')


            class RefWithSchemaKeywords(
                RootModel[constr(pattern=r'^\S(.*\S)?$', min_length=5, max_length=100)]
            ):
                root: constr(pattern=r'^\S(.*\S)?$', min_length=5, max_length=100) = Field(
                    ..., description='Ref with additional schema keywords.'
                )


            class ArrayDatatype(RootModel[list[str]]):
                root: list[str]


            class RefToArrayAllOf(BaseModel):
                pass


            class ObjectNoPropsDatatype(BaseModel):
                pass


            class RefToObjectNoPropsAllOf(ObjectNoPropsDatatype):
                pass


            class PatternPropsDatatype(RootModel[dict[constr(pattern=r'^S_'), str]]):
                root: dict[constr(pattern=r'^S_'), str]


            class RefToPatternPropsAllOf(BaseModel):
                pass


            class NestedAllOfDatatype(RootModel[constr(min_length=1)]):
                root: constr(min_length=1)


            class RefToNestedAllOfAllOf(RootModel[constr(min_length=1, max_length=100)]):
                root: constr(min_length=1, max_length=100) = Field(
                    ..., description='Ref to nested allOf root model.'
                )


            class ConstraintsOnlyDatatype(RootModel[Any]):
                root: Any = Field(..., description='Constraints only, no type.')


            class RefToConstraintsOnlyAllOf(RootModel[Any]):
                root: Any = Field(..., description='Ref to constraints-only schema.')


            class NoDescriptionAllOf(RootModel[constr(pattern=r'^\S(.*\S)?$', min_length=5)]):
                root: constr(pattern=r'^\S(.*\S)?$', min_length=5) = Field(
                    ..., description='A base string type.'
                )


            class EmptyConstraintItemAllOf(
                RootModel[constr(pattern=r'^\S(.*\S)?$', max_length=50)]
            ):
                root: constr(pattern=r'^\S(.*\S)?$', max_length=50) = Field(
                    ..., description='AllOf with empty constraint item.'
                )


            class ConflictingFormatAllOf(BaseModel):
                pass


            class Model(BaseModel):
                name: ConstrainedStringDatatype | None = None
                count: NonNegativeIntegerDatatype | None = None
                percentage: BoundedIntegerDatatype | None = None
                email: EmailDatatype | None = None
                obj: ObjectWithAllOf | None = None
                multi: MultiRefAllOf | None = None
                noconstraint: NoConstraintAllOf | None = None
                incompatible: IncompatibleTypeAllOf | None = None
                withprops: ConstraintWithProperties | None = None
                withitems: ConstraintWithItems | None = None
                numint: NumberIntegerCompatible | None = None
                refwithkw: RefWithSchemaKeywords | None = None
                refarr: RefToArrayAllOf | None = None
                refobjnoprops: RefToObjectNoPropsAllOf | None = None
                refpatternprops: RefToPatternPropsAllOf | None = None
                refnestedallof: RefToNestedAllOfAllOf | None = None
                refconstraintsonly: RefToConstraintsOnlyAllOf | None = None
                nodescription: NoDescriptionAllOf | None = None
                emptyconstraint: EmptyConstraintItemAllOf | None = None
                conflictingformat: ConflictingFormatAllOf | None = None
            ```

            <!-- fmt: on -->

---

## `--disable-future-imports` {#disable-future-imports}

Prevent automatic addition of __future__ imports in generated code.

The --disable-future-imports option stops the generator from adding
'from __future__ import annotations' to the output. This is useful when
you need compatibility with tools or environments that don't support
postponed evaluation of annotations (PEP 563).

**See also:** [Python Version Compatibility](../python-version-compatibility.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input keep_model_order_field_references.json --disable-future-imports --target-python-version 3.10 # (1)!
    ```

    1. :material-arrow-left: `--disable-future-imports` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "DescriptionType",
      "type": "object",
      "properties": {
        "metadata": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Metadata"
          }
        }
      },
      "definitions": {
        "Metadata": {
          "title": "Metadata",
          "type": "object",
          "properties": {
            "title": {
              "type": "string"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  keep_model_order_field_references.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from pydantic import BaseModel


    class Metadata(BaseModel):
        title: str | None = None


    class DescriptionType(BaseModel):
        metadata: list[Metadata] | None = None
    ```

    <!-- fmt: on -->

---

## `--enum-field-as-literal` {#enum-field-as-literal}

Convert all enum fields to Literal types instead of Enum classes.

The `--enum-field-as-literal all` flag converts all enum types to Literal
type annotations. This is useful when you want string literal types instead
of Enum classes for all enumerations.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input enums.graphql --enum-field-as-literal all # (1)!
    ```

    1. :material-arrow-left: `--enum-field-as-literal` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: "3.0.0"
        info:
          version: 1.0.0
          title: Swagger Petstore
          license:
            name: MIT
        servers:
          - url: http://petstore.swagger.io/v1
        paths:
          /pets:
            get:
              summary: List all pets
              operationId: listPets
              tags:
                - pets
              parameters:
                - name: limit
                  in: query
                  description: How many items to return at one time (max 100)
                  required: false
                  schema:
                    type: integer
                    format: int32
              responses:
                '200':
                  description: A paged array of pets
                  headers:
                    x-next:
                      description: A link to the next page of responses
                      schema:
                        type: string
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
        components:
          schemas:
            Pet:
              required:
                - id
                - name
                - number
                - boolean
              properties:
                id:
                  type: integer
                  format: int64
                name:
                  type: string
                tag:
                  type: string
                kind:
                  type: string
                  enum: ['dog', 'cat']
                type:
                  type: string
                  enum: [ 'animal' ]
                number:
                  type: integer
                  enum: [ 1 ]
                boolean:
                  type: boolean
                  enum: [ true ]

            Pets:
              type: array
              items:
                $ref: "#/components/schemas/Pet"
            animal:
              type: object
              properties:
                kind:
                  type: string
                  enum: ['snake', 'rabbit']
            Error:
              required:
                - code
                - message
              properties:
                code:
                  type: integer
                  format: int32
                message:
                  type: string
            EnumObject:
              type: object
              properties:
                type:
                  enum: ['a', 'b']
                  type: string
            EnumRoot:
              enum: ['a', 'b']
              type: string
            IntEnum:
              enum: [1,2]
              type: number
            AliasEnum:
              enum: [1,2,3]
              type: number
              x-enum-varnames: ['a', 'b', 'c']
            MultipleTypeEnum:
              enum: [ "red", "amber", "green", null, 42 ]
            singleEnum:
              enum: [ "pet" ]
              type: string
            arrayEnum:
              type: array
              items: [
                { enum: [ "cat" ] },
                { enum: [ "dog"]}
              ]
            nestedNullableEnum:
              type: object
              properties:
                nested_version:
                  type: string
                  nullable: true
                  default: RC1
                  description: nullable enum
                  example: RC2
                  enum:
                    - RC1
                    - RC1N
                    - RC2
                    - RC2N
                    - RC3
                    - RC4
                    - null
            version:
              type: string
              nullable: true
              default: RC1
              description: nullable enum
              example: RC2
              enum:
              - RC1
              - RC1N
              - RC2
              - RC2N
              - RC3
              - RC4
              - null
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  enum_models.yaml
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from enum import Enum
        from typing import Literal

        from pydantic import BaseModel, Field, RootModel


        class Kind(Enum):
            dog = 'dog'
            cat = 'cat'


        class Pet(BaseModel):
            id: int
            name: str
            tag: str | None = None
            kind: Kind | None = None
            type: Literal['animal'] | None = None
            number: Literal[1]
            boolean: Literal[True]


        class Pets(RootModel[list[Pet]]):
            root: list[Pet]


        class Kind1(Enum):
            snake = 'snake'
            rabbit = 'rabbit'


        class Animal(BaseModel):
            kind: Kind1 | None = None


        class Error(BaseModel):
            code: int
            message: str


        class Type(Enum):
            a = 'a'
            b = 'b'


        class EnumObject(BaseModel):
            type: Type | None = None


        class EnumRoot(Enum):
            a = 'a'
            b = 'b'


        class IntEnum(Enum):
            number_1 = 1
            number_2 = 2


        class AliasEnum(Enum):
            a = 1
            b = 2
            c = 3


        class MultipleTypeEnum(Enum):
            red = 'red'
            amber = 'amber'
            green = 'green'
            NoneType_None = None
            int_42 = 42


        class SingleEnum(RootModel[Literal['pet']]):
            root: Literal['pet']


        class ArrayEnum(RootModel[list[Literal['cat'] | Literal['dog']]]):
            root: list[Literal['cat'] | Literal['dog']]


        class NestedVersionEnum(Enum):
            RC1 = 'RC1'
            RC1N = 'RC1N'
            RC2 = 'RC2'
            RC2N = 'RC2N'
            RC3 = 'RC3'
            RC4 = 'RC4'


        class NestedVersion(RootModel[NestedVersionEnum | None]):
            root: NestedVersionEnum | None = Field(
                'RC1', description='nullable enum', examples=['RC2']
            )


        class NestedNullableEnum(BaseModel):
            nested_version: NestedVersion | None = Field(
                'RC1', description='nullable enum', examples=['RC2'], validate_default=True
            )


        class VersionEnum(Enum):
            RC1 = 'RC1'
            RC1N = 'RC1N'
            RC2 = 'RC2'
            RC2N = 'RC2N'
            RC3 = 'RC3'
            RC4 = 'RC4'


        class Version(RootModel[VersionEnum | None]):
            root: VersionEnum | None = Field(
                'RC1', description='nullable enum', examples=['RC2']
            )
        ```

        <!-- fmt: on -->

    === "JSON Schema"

        **Input Schema:**

        ```yaml
        $schema: http://json-schema.org/draft-07/schema#
        type: object
        title: Config
        properties:
          mode:
            title: Mode
            type: string
            oneOf:
              - title: fast
                const: fast
              - title: slow
                const: slow
          modes:
            type: array
            items:
              type: string
              oneOf:
                - const: a
                - const: b
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  oneof_const_enum_nested.yaml
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Literal

        from pydantic import BaseModel, Field


        class Config(BaseModel):
            mode: Literal['fast', 'slow'] | None = Field(None, title='Mode')
            modes: list[Literal['a', 'b']] | None = None
        ```

        <!-- fmt: on -->

    === "GraphQL"

        **Input Schema:**

        ```graphql
        "Employee shift status"
        enum EmployeeShiftStatus {
          "not on shift"
          NOT_ON_SHIFT
          "on shift"
          ON_SHIFT
        }

        enum Color {
          RED
          GREEN
          BLUE
        }

        enum EnumWithOneField {
            FIELD
        }
        ```

        **Output:**

        === "With Option"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  enums.graphql
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from typing import Literal

            from pydantic import RootModel
            from typing_extensions import TypeAliasType

            Boolean = TypeAliasType("Boolean", bool)
            """
            The `Boolean` scalar type represents `true` or `false`.
            """


            String = TypeAliasType("String", str)
            """
            The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
            """


            class Color(RootModel[Literal['BLUE', 'GREEN', 'RED']]):
                root: Literal['BLUE', 'GREEN', 'RED']


            class EmployeeShiftStatus(RootModel[Literal['NOT_ON_SHIFT', 'ON_SHIFT']]):
                """
                Employee shift status
                """

                root: Literal['NOT_ON_SHIFT', 'ON_SHIFT']


            class EnumWithOneField(RootModel[Literal['FIELD']]):
                root: Literal['FIELD']
            ```

            <!-- fmt: on -->

        === "Without Option"

            <!-- fmt: off -->

            ```python
            # generated by datamodel-codegen:
            #   filename:  enums.graphql
            #   timestamp: 2019-07-26T00:00:00+00:00

            from __future__ import annotations

            from enum import Enum

            from typing_extensions import TypeAliasType

            Boolean = TypeAliasType("Boolean", bool)
            """
            The `Boolean` scalar type represents `true` or `false`.
            """


            String = TypeAliasType("String", str)
            """
            The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
            """


            class Color(Enum):
                BLUE = 'BLUE'
                GREEN = 'GREEN'
                RED = 'RED'


            class EmployeeShiftStatus(Enum):
                """
                Employee shift status
                """

                NOT_ON_SHIFT = 'NOT_ON_SHIFT'
                ON_SHIFT = 'ON_SHIFT'


            class EnumWithOneField(Enum):
                FIELD = 'FIELD'
            ```

            <!-- fmt: on -->

---

## `--enum-field-as-literal-map` {#enum-field-as-literal-map}

Override enum/literal generation per-field via JSON mapping.

The `--enum-field-as-literal-map` option allows per-field control over whether
to generate Literal types or Enum classes. Overrides `--enum-field-as-literal`.

You can pass the mapping either inline as JSON or as a path to a JSON file.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input enum_field_as_literal_map.json --enum-field-as-literal-map '{"status": "literal"}' # (1)!
    ```

    1. :material-arrow-left: `--enum-field-as-literal-map` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "EnumFieldAsLiteralMap",
      "type": "object",
      "properties": {
        "status": {
          "title": "Status",
          "type": "string",
          "enum": ["active", "inactive", "pending"]
        },
        "priority": {
          "title": "Priority",
          "type": "string",
          "enum": ["high", "medium", "low"]
        },
        "category": {
          "title": "Category",
          "type": "string",
          "enum": ["a", "b", "c"]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  enum_field_as_literal_map.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum
    from typing import Literal

    from pydantic import BaseModel, Field


    class Priority(Enum):
        high = 'high'
        medium = 'medium'
        low = 'low'


    class Category(Enum):
        a = 'a'
        b = 'b'
        c = 'c'


    class EnumFieldAsLiteralMap(BaseModel):
        status: Literal['active', 'inactive', 'pending'] | None = Field(
            None, title='Status'
        )
        priority: Priority | None = Field(None, title='Priority')
        category: Category | None = Field(None, title='Category')
    ```

    <!-- fmt: on -->

---

## `--ignore-enum-constraints` {#ignore-enum-constraints}

Ignore enum constraints and use base string type instead of Enum classes.

The `--ignore-enum-constraints` flag ignores enum constraints and uses
the base type (str) instead of generating Enum classes. This is useful
when you need flexibility in the values a field can accept beyond the
defined enum members.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input enums.graphql --ignore-enum-constraints # (1)!
    ```

    1. :material-arrow-left: `--ignore-enum-constraints` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    "Employee shift status"
    enum EmployeeShiftStatus {
      "not on shift"
      NOT_ON_SHIFT
      "on shift"
      ON_SHIFT
    }

    enum Color {
      RED
      GREEN
      BLUE
    }

    enum EnumWithOneField {
        FIELD
    }
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  enums.graphql
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import RootModel
        from typing_extensions import TypeAliasType

        Boolean = TypeAliasType("Boolean", bool)
        """
        The `Boolean` scalar type represents `true` or `false`.
        """


        String = TypeAliasType("String", str)
        """
        The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
        """


        class Color(RootModel[str]):
            root: str


        class EmployeeShiftStatus(RootModel[str]):
            """
            Employee shift status
            """

            root: str


        class EnumWithOneField(RootModel[str]):
            root: str
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  enums.graphql
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from enum import Enum

        from typing_extensions import TypeAliasType

        Boolean = TypeAliasType("Boolean", bool)
        """
        The `Boolean` scalar type represents `true` or `false`.
        """


        String = TypeAliasType("String", str)
        """
        The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
        """


        class Color(Enum):
            BLUE = 'BLUE'
            GREEN = 'GREEN'
            RED = 'RED'


        class EmployeeShiftStatus(Enum):
            """
            Employee shift status
            """

            NOT_ON_SHIFT = 'NOT_ON_SHIFT'
            ON_SHIFT = 'ON_SHIFT'


        class EnumWithOneField(Enum):
            FIELD = 'FIELD'
        ```

        <!-- fmt: on -->

---

## `--import-overrides` {#import-overrides}

Override modules for generated imports by symbol name.

The mapping applies to imports in generated output regardless of their original module, except for
`__future__` imports. This is useful for routing typing helpers through a project compatibility module
across Python target versions.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input datetime.json --output-model-type typing.TypedDict --target-python-version 3.10 --import-overrides '{"TypedDict": "my_project.typing_compat", "NotRequired": "my_project.typing_compat"}' # (1)!
    ```

    1. :material-arrow-left: `--import-overrides` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "User": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "example": "ken"
            },
            "birthDay": {
              "type": "string",
              "format": "date-time",
              "example": "2016-08-29T09:12:33.001Z"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  datetime.json
    #   timestamp: 1985-10-26T08:21:00+00:00

    from __future__ import annotations

    from typing import Any, TypeAlias

    from my_project.typing_compat import NotRequired, TypedDict

    Model: TypeAlias = Any


    class User(TypedDict):
        name: NotRequired[str]
        birthDay: NotRequired[str]
    ```

    <!-- fmt: on -->

---

## `--no-use-closed-typed-dict` {#no-use-closed-typed-dict}

Disable PEP 728 TypedDict closed/extra_items generation.

Use this option for compatibility with type checkers that don't yet support PEP 728
(e.g., mypy). TypedDict will be generated without `closed=True` or `extra_items`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input typed_dict_closed.json --output-model-type typing.TypedDict --no-use-closed-typed-dict # (1)!
    ```

    1. :material-arrow-left: `--no-use-closed-typed-dict` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "title": "ClosedModel",
      "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer"}
      },
      "required": ["name"],
      "additionalProperties": false
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  typed_dict_closed.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import TypedDict

    from typing_extensions import NotRequired


    class ClosedModel(TypedDict):
        name: str
        age: NotRequired[int]
    ```

    <!-- fmt: on -->

---

## `--no-use-specialized-enum` {#no-use-specialized-enum}

Disable specialized Enum classes for Python 3.11+ code generation.

The `--no-use-specialized-enum` flag prevents the generator from using
specialized Enum classes (StrEnum, IntEnum) when generating code for
Python 3.11+, falling back to standard Enum classes instead.

**Related:** [`--target-python-version`](model-customization.md#target-python-version), [`--use-specialized-enum`](#use-specialized-enum), [`--use-subclass-enum`](model-customization.md#use-subclass-enum)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input enums.graphql --target-python-version 3.11 --no-use-specialized-enum # (1)!
    ```

    1. :material-arrow-left: `--no-use-specialized-enum` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```json
        {
          "openapi": "3.0.2",
          "components": {
            "schemas": {
              "ProcessingStatus": {
                "title": "ProcessingStatus",
                "enum": [
                  "COMPLETED",
                  "PENDING",
                  "FAILED"
                ],
                "type": "string",
                "description": "The processing status"
              },
              "ProcessingTask": {
                "title": "ProcessingTask",
                "type": "object",
                "properties": {
                  "processing_status": {
                    "title": "Status of the task",
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/ProcessingStatus"
                      }
                    ],
                    "default": "COMPLETED"
                  }
                }
              },
            }
          },
          "info": {
            "title": "",
            "version": ""
          },
          "paths": {}
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  subclass_enum.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from enum import Enum

        from pydantic import BaseModel, Field


        class ProcessingStatus(Enum):
            COMPLETED = 'COMPLETED'
            PENDING = 'PENDING'
            FAILED = 'FAILED'


        class ProcessingTask(BaseModel):
            processing_status: ProcessingStatus | None = Field(
                'COMPLETED', title='Status of the task'
            )
        ```

        <!-- fmt: on -->

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "type": "object",
          "properties": {
            "IntEnum": {
              "type": "integer",
              "enum": [
                1,
                2,
                3
              ]
            },
            "FloatEnum": {
              "type": "number",
              "enum": [
                1.1,
                2.1,
                3.1
              ]
            },
            "StrEnum": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3"
              ]
            },
            "NonTypedEnum": {
              "enum": [
                "1",
                "2",
                "3"
              ]
            },
            "BooleanEnum": {
              "type": "boolean",
              "enum": [
                true,
                false
              ]
            },
            "UnknownEnum": {
              "type": "unknown",
              "enum": [
                "a",
                "b"
              ]
            }
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  subclass_enum.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from enum import Enum

        from pydantic import BaseModel, Field


        class IntEnum(Enum):
            integer_1 = 1
            integer_2 = 2
            integer_3 = 3


        class FloatEnum(Enum):
            number_1_1 = 1.1
            number_2_1 = 2.1
            number_3_1 = 3.1


        class StrEnum(Enum):
            field_1 = '1'
            field_2 = '2'
            field_3 = '3'


        class NonTypedEnum(Enum):
            field_1 = '1'
            field_2 = '2'
            field_3 = '3'


        class BooleanEnum(Enum):
            boolean_True = True
            boolean_False = False


        class UnknownEnum(Enum):
            a = 'a'
            b = 'b'


        class Model(BaseModel):
            IntEnum_1: IntEnum | None = Field(None, alias='IntEnum')
            FloatEnum_1: FloatEnum | None = Field(None, alias='FloatEnum')
            StrEnum_1: StrEnum | None = Field(None, alias='StrEnum')
            NonTypedEnum_1: NonTypedEnum | None = Field(None, alias='NonTypedEnum')
            BooleanEnum_1: BooleanEnum | None = Field(None, alias='BooleanEnum')
            UnknownEnum_1: UnknownEnum | None = Field(None, alias='UnknownEnum')
        ```

        <!-- fmt: on -->

    === "GraphQL"

        **Input Schema:**

        ```graphql
        "Employee shift status"
        enum EmployeeShiftStatus {
          "not on shift"
          NOT_ON_SHIFT
          "on shift"
          ON_SHIFT
        }

        enum Color {
          RED
          GREEN
          BLUE
        }

        enum EnumWithOneField {
            FIELD
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  enums.graphql
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from enum import Enum

        from typing_extensions import TypeAliasType

        Boolean = TypeAliasType("Boolean", bool)
        """
        The `Boolean` scalar type represents `true` or `false`.
        """


        String = TypeAliasType("String", str)
        """
        The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
        """


        class Color(Enum):
            BLUE = 'BLUE'
            GREEN = 'GREEN'
            RED = 'RED'


        class EmployeeShiftStatus(Enum):
            """
            Employee shift status
            """

            NOT_ON_SHIFT = 'NOT_ON_SHIFT'
            ON_SHIFT = 'ON_SHIFT'


        class EnumWithOneField(Enum):
            FIELD = 'FIELD'
        ```

        <!-- fmt: on -->

---

## `--no-use-standard-collections` {#no-use-standard-collections}

Use typing.Dict/List instead of built-in dict/list for container types.

The `--no-use-standard-collections` flag generates typing module containers
(Dict, List) instead of built-in types. This is useful for older Python
versions or when explicit typing imports are preferred.

**Related:** [`--use-standard-collections`](#use-standard-collections)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input root_model_with_additional_properties.json --no-use-standard-collections # (1)!
    ```

    1. :material-arrow-left: `--no-use-standard-collections` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$id": "test.json",
      "description": "test",
      "type": "object",
      "required": [
        "test_id",
        "test_ip",
        "result",
        "nested_object_result",
        "nested_enum_result"
      ],
      "properties": {
        "test_id": {
          "type": "string",
          "description": "test ID"
        },
        "test_ip": {
          "type": "string",
          "description": "test IP"
        },
        "result": {
          "type": "object",
          "additionalProperties": {
            "type": "integer"
          }
        },
        "nested_object_result": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "status":{
                "type": "integer"
              }
            },
            "required": ["status"]
          }
        },
        "nested_enum_result": {
          "type": "object",
          "additionalProperties": {
            "enum": ["red", "green"]
          }
        },
        "all_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "allOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "one_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "oneOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "any_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "anyOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "all_of_with_unknown_object" :{
          "type" : "object",
          "additionalProperties" :
          {
            "allOf" : [
              { "$ref" : "#/definitions/User" },
              { "description": "TODO" }
            ]
          }
        },
        "objectRef": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/User"
          }
        },
        "deepNestedObjectRef": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                 "$ref": "#/definitions/User"
              }
            }
          }
        }
      },
      "definitions": {
        "User": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  root_model_with_additional_properties.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum
    from typing import Dict

    from pydantic import BaseModel, Field


    class NestedObjectResult(BaseModel):
        status: int


    class NestedEnumResult(Enum):
        red = 'red'
        green = 'green'


    class OneOfResult(BaseModel):
        description: str | None = None


    class AnyOfResult(BaseModel):
        description: str | None = None


    class User(BaseModel):
        name: str | None = None


    class AllOfResult(User):
        description: str | None = None


    class Model(BaseModel):
        test_id: str = Field(..., description='test ID')
        test_ip: str = Field(..., description='test IP')
        result: Dict[str, int]
        nested_object_result: Dict[str, NestedObjectResult]
        nested_enum_result: Dict[str, NestedEnumResult]
        all_of_result: Dict[str, AllOfResult] | None = None
        one_of_result: Dict[str, User | OneOfResult] | None = None
        any_of_result: Dict[str, User | AnyOfResult] | None = None
        all_of_with_unknown_object: Dict[str, User] | None = None
        objectRef: Dict[str, User] | None = None
        deepNestedObjectRef: Dict[str, Dict[str, Dict[str, User]]] | None = None
    ```

    <!-- fmt: on -->

---

## `--no-use-union-operator` {#no-use-union-operator}

Use Union[X, Y] / Optional[X] instead of X | Y union operator.

The `--no-use-union-operator` flag generates union types using typing.Union
and typing.Optional instead of the | operator (PEP 604). This is useful
for older Python versions or when explicit typing imports are preferred.

**Related:** [`--use-union-operator`](#use-union-operator)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input root_model_with_additional_properties.json --no-use-union-operator # (1)!
    ```

    1. :material-arrow-left: `--no-use-union-operator` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$id": "test.json",
      "description": "test",
      "type": "object",
      "required": [
        "test_id",
        "test_ip",
        "result",
        "nested_object_result",
        "nested_enum_result"
      ],
      "properties": {
        "test_id": {
          "type": "string",
          "description": "test ID"
        },
        "test_ip": {
          "type": "string",
          "description": "test IP"
        },
        "result": {
          "type": "object",
          "additionalProperties": {
            "type": "integer"
          }
        },
        "nested_object_result": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "status":{
                "type": "integer"
              }
            },
            "required": ["status"]
          }
        },
        "nested_enum_result": {
          "type": "object",
          "additionalProperties": {
            "enum": ["red", "green"]
          }
        },
        "all_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "allOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "one_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "oneOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "any_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "anyOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "all_of_with_unknown_object" :{
          "type" : "object",
          "additionalProperties" :
          {
            "allOf" : [
              { "$ref" : "#/definitions/User" },
              { "description": "TODO" }
            ]
          }
        },
        "objectRef": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/User"
          }
        },
        "deepNestedObjectRef": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                 "$ref": "#/definitions/User"
              }
            }
          }
        }
      },
      "definitions": {
        "User": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  root_model_with_additional_properties.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum
    from typing import Optional, Union

    from pydantic import BaseModel, Field


    class NestedObjectResult(BaseModel):
        status: int


    class NestedEnumResult(Enum):
        red = 'red'
        green = 'green'


    class OneOfResult(BaseModel):
        description: Optional[str] = None


    class AnyOfResult(BaseModel):
        description: Optional[str] = None


    class User(BaseModel):
        name: Optional[str] = None


    class AllOfResult(User):
        description: Optional[str] = None


    class Model(BaseModel):
        test_id: str = Field(..., description='test ID')
        test_ip: str = Field(..., description='test IP')
        result: dict[str, int]
        nested_object_result: dict[str, NestedObjectResult]
        nested_enum_result: dict[str, NestedEnumResult]
        all_of_result: Optional[dict[str, AllOfResult]] = None
        one_of_result: Optional[dict[str, Union[User, OneOfResult]]] = None
        any_of_result: Optional[dict[str, Union[User, AnyOfResult]]] = None
        all_of_with_unknown_object: Optional[dict[str, User]] = None
        objectRef: Optional[dict[str, User]] = None
        deepNestedObjectRef: Optional[dict[str, dict[str, dict[str, User]]]] = None
    ```

    <!-- fmt: on -->

---

## `--output-date-class` {#output-date-class}

Specify date class type for date schema fields.

The `--output-date-class` flag controls which date type to use for fields
with date format. Options include 'PastDate' for past dates only
or 'FutureDate' for future dates only. This is a Pydantic v2 only feature.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input date_class.yaml --output-date-class PastDate # (1)!
    ```

    1. :material-arrow-left: `--output-date-class` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    components:
      schemas:
        Event:
          type: object
          required:
            - eventDate
          properties:
            eventDate:
              type: string
              format: date
              example: 2023-12-25
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  date_class.yaml
    #   timestamp: 1985-10-26T08:21:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field, PastDate


    class Event(BaseModel):
        eventDate: PastDate = Field(..., examples=['2023-12-25'])
    ```

    <!-- fmt: on -->

---

## `--output-datetime-class` {#output-datetime-class}

Specify datetime class type for date-time schema fields.

The `--output-datetime-class` flag controls which datetime type to use for fields
with date-time format. Options include 'AwareDatetime' for timezone-aware datetimes
or 'datetime' for standard Python datetime objects.

**See also:** [Type Mappings and Custom Types](../type-mappings.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input datetime.yaml --output-datetime-class AwareDatetime # (1)!
    ```

    1. :material-arrow-left: `--output-datetime-class` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    components:
      schemas:
        InventoryItem:
          required:
    #      - id
    #      - name
          - releaseDate
          type: object
          properties:
    #        id:
    #          type: string
    #          format: uuid
    #          example: d290f1ee-6c54-4b01-90e6-d701748f0851
    #        name:
    #          type: string
    #          example: Widget Adapter
            releaseDate:
              type: string
              format: date-time
              example: 2016-08-29T09:12:33.001Z
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  datetime.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AwareDatetime, BaseModel, Field


    class InventoryItem(BaseModel):
        releaseDate: AwareDatetime = Field(..., examples=['2016-08-29T09:12:33.001Z'])
    ```

    <!-- fmt: on -->

---

## `--strict-types` {#strict-types}

Enable strict type validation for specified Python types.

The --strict-types option enforces stricter type checking by preventing implicit
type coercion for the specified types (str, bytes, int, float, bool). This
generates StrictStr, StrictBytes, StrictInt, StrictFloat, and StrictBool types
in Pydantic models, ensuring values match exactly without automatic conversion.

**See also:** [Type Mappings and Custom Types](../type-mappings.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input strict_types.json --strict-types str bytes int float bool # (1)!
    ```

    1. :material-arrow-left: `--strict-types` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "User",
      "type": "object",
      "properties": {
            "name": {
              "type": "string",
              "example": "ken"
            },
            "age": {
              "type": "integer"
            },
            "salary": {
              "type": "integer",
              "minimum": 0
            },
            "debt" : {
              "type": "integer",
              "maximum": 0
            },
            "loan" : {
              "type": "number",
              "maximum": 0
            },
            "tel": {
              "type": "string",
              "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
            },
            "height": {
              "type": "number",
              "minimum": 0
            },
            "weight": {
              "type": "number",
              "minimum": 0
            },
            "score": {
              "type": "number",
              "minimum": 1e-08
            },
            "active": {
              "type": "boolean"
            },
            "photo": {
              "type": "string",
              "format": "binary",
              "minLength": 100
            }
          }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  strict_types.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import (
        BaseModel,
        Field,
        StrictBool,
        StrictInt,
        StrictStr,
        conbytes,
        confloat,
        conint,
        constr,
    )


    class User(BaseModel):
        name: StrictStr | None = Field(None, examples=['ken'])
        age: StrictInt | None = None
        salary: conint(ge=0, strict=True) | None = None
        debt: conint(le=0, strict=True) | None = None
        loan: confloat(le=0.0, strict=True) | None = None
        tel: constr(
            pattern=r'^(\([0-9]{3}\))?[0-9]{3}-[0-9]{4}$', strict=True
        ) | None = None
        height: confloat(ge=0.0, strict=True) | None = None
        weight: confloat(ge=0.0, strict=True) | None = None
        score: confloat(ge=1e-08, strict=True) | None = None
        active: StrictBool | None = None
        photo: conbytes(min_length=100, strict=True) | None = None
    ```

    <!-- fmt: on -->

---

## `--type-mappings` {#type-mappings}

Override default type mappings for schema formats.

The `--type-mappings` flag configures the code generation behavior.

**See also:** [Type Mappings and Custom Types](../type-mappings.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input type_mappings.json --output-model-type pydantic_v2.BaseModel --type-mappings binary=string # (1)!
    ```

    1. :material-arrow-left: `--type-mappings` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "BlobModel",
      "type": "object",
      "properties": {
        "content": {
          "type": "string",
          "format": "binary",
          "description": "Binary content that should be mapped to string"
        },
        "data": {
          "type": "string",
          "format": "byte",
          "description": "Base64 encoded data"
        },
        "name": {
          "type": "string",
          "description": "Regular string field"
        }
      },
      "required": ["content", "data", "name"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  type_mappings.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import Base64Str, BaseModel, Field


    class BlobModel(BaseModel):
        content: str = Field(
            ..., description='Binary content that should be mapped to string'
        )
        data: Base64Str = Field(..., description='Base64 encoded data')
        name: str = Field(..., description='Regular string field')
    ```

    <!-- fmt: on -->

---

## `--type-overrides` {#type-overrides}

Replace schema model types with custom Python types via JSON mapping.

This option is useful for importing models from external libraries (like `geojson-pydantic`)
instead of generating them.

**Override Formats:**

| Format | Description |
|--------|-------------|
| `{"ModelName": "package.Type"}` | Model-level: Skip generation; replace field and inheritance refs |
| `{"Model.field": "package.Type"}` | Scoped: Override only specific field in specific model |

**Common Use Cases:**

| Use Case | Example Override |
|----------|------------------|
| GeoJSON types | `{"Feature": "geojson_pydantic.Feature"}` |
| Custom datetime | `{"Timestamp": "pendulum.DateTime"}` |
| MongoDB ObjectId | `{"ObjectId": "bson.ObjectId"}` |
| Custom validators | `{"Email": "my_app.types.ValidatedEmail"}` |

!!! tip "Usage"

    ```bash
    datamodel-codegen --input type_overrides_test.json --type-overrides '{"CustomType": "my_app.types.CustomType"}' # (1)!
    ```

    1. :material-arrow-left: `--type-overrides` - the option documented here

!!! note "Model-level overrides skip generation"
    When you specify a model-level override (without a dot in the key), the generator will
    **skip generating that model entirely** and import it from the specified package instead.
    References to that model are replaced in field annotations and `allOf` inheritance base classes.


??? example "Examples"

    **Input Schema:**

    ```json
    {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
            "CustomType": {"type": "string"},
            "User": {
                "type": "object",
                "properties": {
                    "id": {"type": "integer"},
                    "custom": {"$ref": "#/definitions/CustomType"}
                }
            }
        }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  type_overrides_test.json
    #   timestamp: 1985-10-26T08:21:00+00:00

    from __future__ import annotations

    from typing import Any

    from my_app.types import CustomType
    from pydantic import BaseModel, RootModel


    class Model(RootModel[Any]):
        root: Any


    class User(BaseModel):
        id: int | None = None
        custom: CustomType | None = None
    ```

    <!-- fmt: on -->

---

## `--use-annotated` {#use-annotated}

Use typing.Annotated for Field() with constraints.

The `--use-annotated` flag generates Field definitions using typing.Annotated
syntax instead of default values. This also enables `--field-constraints`.

`--use-annotated` alone does not preserve `uniqueItems: true` as set semantics.
Use [`--use-unique-items-as-set`](#use-unique-items-as-set) when you need the
generated type to enforce uniqueness for array schemas.

**Related:** [`--field-constraints`](field-customization.md#field-constraints)

**See also:** [Python Version Compatibility](../python-version-compatibility.md)

**Option relationships:**

- **Implies:** [`--field-constraints`](field-customization.md#field-constraints) enabled

!!! tip "Usage"

    ```bash
    datamodel-codegen --input annotated.graphql --output-model-type pydantic_v2.BaseModel --use-annotated # (1)!
    ```

    1. :material-arrow-left: `--use-annotated` - the option documented here

??? example "Examples"

    === "OpenAPI"

        **Input Schema:**

        ```yaml
        openapi: "3.0.0"
        info:
          version: 1.0.0
          title: Swagger Petstore
          license:
            name: MIT
        servers:
          - url: http://petstore.swagger.io/v1
        paths:
          /pets:
            get:
              summary: List all pets
              operationId: listPets
              tags:
                - pets
              parameters:
                - name: limit
                  in: query
                  description: How many items to return at one time (max 100)
                  required: false
                  schema:
                    type: integer
                    format: int32
                    minimum: 0
                    maximum: 100
              responses:
                '200':
                  description: A paged array of pets
                  headers:
                    x-next:
                      description: A link to the next page of responses
                      schema:
                        type: string
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
            post:
              summary: Create a pet
              operationId: createPets
              tags:
                - pets
              responses:
                '201':
                  description: Null response
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
                        x-amazon-apigateway-integration:
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                          passthroughBehavior: when_no_templates
                          httpMethod: POST
                          type: aws_proxy
          /pets/{petId}:
            get:
              summary: Info for a specific pet
              operationId: showPetById
              tags:
                - pets
              parameters:
                - name: petId
                  in: path
                  required: true
                  description: The id of the pet to retrieve
                  schema:
                    type: string
              responses:
                '200':
                  description: Expected response to a valid request
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Pets"
                default:
                  description: unexpected error
                  content:
                    application/json:
                      schema:
                        $ref: "#/components/schemas/Error"
            x-amazon-apigateway-integration:
              uri:
                Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
              passthroughBehavior: when_no_templates
              httpMethod: POST
              type: aws_proxy
        components:
          schemas:
            Pet:
              required:
                - id
                - name
              properties:
                id:
                  type: integer
                  format: int64
                  minimum: 0
                  maximum: 9223372036854775807
                name:
                  type: string
                  maxLength: 256
                tag:
                  type: string
                  maxLength: 64
            Pets:
              type: array
              items:
                $ref: "#/components/schemas/Pet"
              maxItems: 10
              minItems: 1
              uniqueItems: true
            UID:
              type: integer
              minimum: 0
            Users:
              type: array
              items:
                required:
                  - id
                  - name
                  - uid
                properties:
                  id:
                    type: integer
                    format: int64
                    minimum: 0
                  name:
                    type: string
                    maxLength: 256
                  tag:
                    type: string
                    maxLength: 64
                  uid:
                    $ref: '#/components/schemas/UID'
                  phones:
                    type: array
                    items:
                      type: string
                      minLength: 3
                    maxItems: 10
                  fax:
                    type: array
                    items:
                      type: string
                      minLength: 3
                  height:
                    type:
                      - integer
                      - number
                    minimum: 1
                    maximum: 300
                  weight:
                    type:
                      - number
                      - integer
                    minimum: 1.0
                    maximum: 1000.0
                  age:
                    type: integer
                    minimum: 0.0
                    maximum: 200.0
                    exclusiveMinimum: true
                  rating:
                    type: number
                    minimum: 0
                    exclusiveMinimum: true
                    maximum: 5

            Id:
              type: string
            Rules:
              type: array
              items:
                type: string
            Error:
              required:
                - code
                - message
              properties:
                code:
                  type: integer
                  format: int32
                message:
                  type: string
            apis:
              type: array
              items:
                type: object
                properties:
                  apiKey:
                    type: string
                    description: To be used as a dataset parameter value
                  apiVersionNumber:
                    type: string
                    description: To be used as a version parameter value
                  apiUrl:
                    type: string
                    format: uri
                    minLength: 1
                    description: "The URL describing the dataset's fields"
                  apiDocumentationUrl:
                    type: string
                    format: uri
                    description: A URL to the API console for each API
            Event:
              type: object
              properties:
                name:
                  type: string
            Result:
                type: object
                properties:
                  event:
                    $ref: '#/components/schemas/Event'
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  api_constrained.yaml
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Annotated

        from pydantic import AnyUrl, BaseModel, Field, RootModel


        class Pet(BaseModel):
            id: Annotated[int, Field(ge=0, le=9223372036854775807)]
            name: Annotated[str, Field(max_length=256)]
            tag: Annotated[str | None, Field(max_length=64)] = None


        class Pets(RootModel[list[Pet]]):
            root: Annotated[list[Pet], Field(max_length=10, min_length=1)]


        class UID(RootModel[int]):
            root: Annotated[int, Field(ge=0)]


        class Phone(RootModel[str]):
            root: Annotated[str, Field(min_length=3)]


        class FaxItem(RootModel[str]):
            root: Annotated[str, Field(min_length=3)]


        class User(BaseModel):
            id: Annotated[int, Field(ge=0)]
            name: Annotated[str, Field(max_length=256)]
            tag: Annotated[str | None, Field(max_length=64)] = None
            uid: UID
            phones: Annotated[list[Phone] | None, Field(max_length=10)] = None
            fax: list[FaxItem] | None = None
            height: Annotated[int | float | None, Field(ge=1.0, le=300.0)] = None
            weight: Annotated[float | int | None, Field(ge=1.0, le=1000.0)] = None
            age: Annotated[int | None, Field(gt=0, le=200)] = None
            rating: Annotated[float | None, Field(gt=0.0, le=5.0)] = None


        class Users(RootModel[list[User]]):
            root: list[User]


        class Id(RootModel[str]):
            root: str


        class Rules(RootModel[list[str]]):
            root: list[str]


        class Error(BaseModel):
            code: int
            message: str


        class Api(BaseModel):
            apiKey: Annotated[
                str | None, Field(description='To be used as a dataset parameter value')
            ] = None
            apiVersionNumber: Annotated[
                str | None, Field(description='To be used as a version parameter value')
            ] = None
            apiUrl: Annotated[
                AnyUrl | None, Field(description="The URL describing the dataset's fields")
            ] = None
            apiDocumentationUrl: Annotated[
                AnyUrl | None, Field(description='A URL to the API console for each API')
            ] = None


        class Apis(RootModel[list[Api]]):
            root: list[Api]


        class Event(BaseModel):
            name: str | None = None


        class Result(BaseModel):
            event: Event | None = None
        ```

        <!-- fmt: on -->

    === "GraphQL"

        **Input Schema:**

        ```graphql
        type A {
            field: String!
            optionalField: String
            listField: [String!]!
            listOptionalField: [String]!
            optionalListField: [String!]
            optionalListOptionalField: [String]
            listListField:[[String!]!]!
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  annotated.graphql
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Annotated, Literal

        from pydantic import BaseModel, Field
        from typing_extensions import TypeAliasType

        Boolean = TypeAliasType("Boolean", bool)
        """
        The `Boolean` scalar type represents `true` or `false`.
        """


        String = TypeAliasType("String", str)
        """
        The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
        """


        class A(BaseModel):
            field: String
            listField: list[String]
            listListField: list[list[String]]
            listOptionalField: list[String | None]
            optionalField: String | None = None
            optionalListField: list[String] | None = None
            optionalListOptionalField: list[String | None] | None = None
            typename__: Annotated[Literal['A'] | None, Field(alias='__typename')] = 'A'
        ```

        <!-- fmt: on -->

---

## `--use-closed-typed-dict` {#use-closed-typed-dict}

Generate TypedDict with PEP 728 closed/extra_items (default: enabled).

When enabled (default), generates TypedDict with PEP 728 `closed=True` or `extra_items`
parameters based on `additionalProperties` constraints in the schema.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input typed_dict_closed.json --output-model-type typing.TypedDict --use-closed-typed-dict # (1)!
    ```

    1. :material-arrow-left: `--use-closed-typed-dict` - the option documented here

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: cli-reference.typing-customization.use-closed-typed-dict.example -->
??? example "Examples"

    **Input Schema:**
    <!-- fmt: off -->

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "title": "ClosedModel",
      "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer"}
      },
      "required": ["name"],
      "additionalProperties": false
    }
    ```

    <!-- fmt: on -->

    **Output:**
    <!-- fmt: off -->

    ```python
    from __future__ import annotations

    from typing_extensions import NotRequired, TypedDict


    class ClosedModel(TypedDict, closed=True):
        name: str
        age: NotRequired[int]
    ```

    <!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: cli-reference.typing-customization.use-closed-typed-dict.example -->

---

## `--use-decimal-for-multiple-of` {#use-decimal-for-multiple-of}

Generate Decimal types for fields with multipleOf constraint.

The `--use-decimal-for-multiple-of` flag generates `condecimal` or `Decimal`
types for numeric fields that have a `multipleOf` constraint. This ensures
precise decimal arithmetic when validating values against the constraint.

**See also:** [Type Mappings and Custom Types](../type-mappings.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_decimal_for_multiple_of.json --use-decimal-for-multiple-of # (1)!
    ```

    1. :material-arrow-left: `--use-decimal-for-multiple-of` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "type": "object",
      "properties": {
        "price": {
          "type": "number",
          "multipleOf": 0.01,
          "minimum": 0,
          "maximum": 99999.99
        },
        "quantity": {
          "type": "number",
          "multipleOf": 0.1
        },
        "rate": {
          "type": "number",
          "multipleOf": 0.001,
          "exclusiveMinimum": 0,
          "exclusiveMaximum": 1
        },
        "simple_float": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  use_decimal_for_multiple_of.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from decimal import Decimal

    from pydantic import BaseModel, condecimal, confloat


    class Model(BaseModel):
        price: (
            condecimal(ge=Decimal('0'), le=Decimal('99999.99'), multiple_of=Decimal('0.01'))
            | None
        ) = None
        quantity: condecimal(multiple_of=Decimal('0.1')) | None = None
        rate: (
            condecimal(multiple_of=Decimal('0.001'), lt=Decimal('1.0'), gt=Decimal('0.0'))
            | None
        ) = None
        simple_float: confloat(ge=0.0, le=100.0) | None = None
    ```

    <!-- fmt: on -->

---

## `--use-generic-container-types` {#use-generic-container-types}

Use generic container types (Sequence, Mapping) for type hinting.

The `--use-generic-container-types` flag generates abstract container types
(Sequence, Mapping, FrozenSet) instead of concrete types (list, dict, set).
If `--use-standard-collections` is set, imports from `collections.abc`;
otherwise imports from `typing`.

**Related:** [`--use-standard-collections`](#use-standard-collections)

**See also:** [Python Version Compatibility](../python-version-compatibility.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input root_model_with_additional_properties.json --use-generic-container-types # (1)!
    ```

    1. :material-arrow-left: `--use-generic-container-types` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$id": "test.json",
      "description": "test",
      "type": "object",
      "required": [
        "test_id",
        "test_ip",
        "result",
        "nested_object_result",
        "nested_enum_result"
      ],
      "properties": {
        "test_id": {
          "type": "string",
          "description": "test ID"
        },
        "test_ip": {
          "type": "string",
          "description": "test IP"
        },
        "result": {
          "type": "object",
          "additionalProperties": {
            "type": "integer"
          }
        },
        "nested_object_result": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "status":{
                "type": "integer"
              }
            },
            "required": ["status"]
          }
        },
        "nested_enum_result": {
          "type": "object",
          "additionalProperties": {
            "enum": ["red", "green"]
          }
        },
        "all_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "allOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "one_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "oneOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "any_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "anyOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "all_of_with_unknown_object" :{
          "type" : "object",
          "additionalProperties" :
          {
            "allOf" : [
              { "$ref" : "#/definitions/User" },
              { "description": "TODO" }
            ]
          }
        },
        "objectRef": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/User"
          }
        },
        "deepNestedObjectRef": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                 "$ref": "#/definitions/User"
              }
            }
          }
        }
      },
      "definitions": {
        "User": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  root_model_with_additional_properties.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from collections.abc import Mapping
    from enum import Enum

    from pydantic import BaseModel, Field


    class NestedObjectResult(BaseModel):
        status: int


    class NestedEnumResult(Enum):
        red = 'red'
        green = 'green'


    class OneOfResult(BaseModel):
        description: str | None = None


    class AnyOfResult(BaseModel):
        description: str | None = None


    class User(BaseModel):
        name: str | None = None


    class AllOfResult(User):
        description: str | None = None


    class Model(BaseModel):
        test_id: str = Field(..., description='test ID')
        test_ip: str = Field(..., description='test IP')
        result: Mapping[str, int]
        nested_object_result: Mapping[str, NestedObjectResult]
        nested_enum_result: Mapping[str, NestedEnumResult]
        all_of_result: Mapping[str, AllOfResult] | None = None
        one_of_result: Mapping[str, User | OneOfResult] | None = None
        any_of_result: Mapping[str, User | AnyOfResult] | None = None
        all_of_with_unknown_object: Mapping[str, User] | None = None
        objectRef: Mapping[str, User] | None = None
        deepNestedObjectRef: Mapping[str, Mapping[str, Mapping[str, User]]] | None = None
    ```

    <!-- fmt: on -->

---

## `--use-non-positive-negative-number-constrained-types` {#use-non-positive-negative-number-constrained-types}

Use NonPositive/NonNegative types for number constraints.

The `--use-non-positive-negative-number-constrained-types` flag generates
Pydantic's NonPositiveInt, NonNegativeInt, NonPositiveFloat, and NonNegativeFloat
types for fields with minimum: 0 or maximum: 0 constraints, instead of using
conint/confloat with ge/le parameters.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_non_positive_negative.json --use-non-positive-negative-number-constrained-types # (1)!
    ```

    1. :material-arrow-left: `--use-non-positive-negative-number-constrained-types` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "NumberConstraints",
      "type": "object",
      "properties": {
        "non_negative_int": {
          "type": "integer",
          "minimum": 0,
          "description": "NonNegativeInt: minimum=0 only"
        },
        "non_positive_int": {
          "type": "integer",
          "maximum": 0,
          "description": "NonPositiveInt: maximum=0 only"
        },
        "non_negative_float": {
          "type": "number",
          "minimum": 0,
          "description": "NonNegativeFloat: minimum=0 only"
        },
        "non_positive_float": {
          "type": "number",
          "maximum": 0,
          "description": "NonPositiveFloat: maximum=0 only"
        },
        "positive_int": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "description": "PositiveInt: exclusiveMinimum=0"
        },
        "negative_int": {
          "type": "integer",
          "exclusiveMaximum": 0,
          "description": "NegativeInt: exclusiveMaximum=0"
        },
        "positive_float": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "PositiveFloat: exclusiveMinimum=0"
        },
        "negative_float": {
          "type": "number",
          "exclusiveMaximum": 0,
          "description": "NegativeFloat: exclusiveMaximum=0"
        },
        "bounded_non_negative_int": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100,
          "description": "NonNegativeInt with additional upper bound"
        },
        "bounded_non_positive_int": {
          "type": "integer",
          "maximum": 0,
          "minimum": -100,
          "description": "NonPositiveInt with additional lower bound"
        },
        "bounded_non_negative_float": {
          "type": "number",
          "minimum": 0,
          "maximum": 1.0,
          "description": "NonNegativeFloat with additional upper bound"
        },
        "bounded_non_positive_float": {
          "type": "number",
          "maximum": 0,
          "minimum": -1.0,
          "description": "NonPositiveFloat with additional lower bound"
        },
        "plain_constrained_int": {
          "type": "integer",
          "minimum": 5,
          "maximum": 100,
          "description": "No zero bound: should remain conint/Field"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  use_non_positive_negative.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import (
        BaseModel,
        Field,
        NegativeFloat,
        NegativeInt,
        NonNegativeFloat,
        NonNegativeInt,
        NonPositiveFloat,
        NonPositiveInt,
        PositiveFloat,
        PositiveInt,
        confloat,
        conint,
    )


    class NumberConstraints(BaseModel):
        non_negative_int: NonNegativeInt | None = Field(
            None, description='NonNegativeInt: minimum=0 only'
        )
        non_positive_int: NonPositiveInt | None = Field(
            None, description='NonPositiveInt: maximum=0 only'
        )
        non_negative_float: NonNegativeFloat | None = Field(
            None, description='NonNegativeFloat: minimum=0 only'
        )
        non_positive_float: NonPositiveFloat | None = Field(
            None, description='NonPositiveFloat: maximum=0 only'
        )
        positive_int: PositiveInt | None = Field(
            None, description='PositiveInt: exclusiveMinimum=0'
        )
        negative_int: NegativeInt | None = Field(
            None, description='NegativeInt: exclusiveMaximum=0'
        )
        positive_float: PositiveFloat | None = Field(
            None, description='PositiveFloat: exclusiveMinimum=0'
        )
        negative_float: NegativeFloat | None = Field(
            None, description='NegativeFloat: exclusiveMaximum=0'
        )
        bounded_non_negative_int: conint(ge=0, le=100) | None = Field(
            None, description='NonNegativeInt with additional upper bound'
        )
        bounded_non_positive_int: conint(ge=-100, le=0) | None = Field(
            None, description='NonPositiveInt with additional lower bound'
        )
        bounded_non_negative_float: confloat(ge=0.0, le=1.0) | None = Field(
            None, description='NonNegativeFloat with additional upper bound'
        )
        bounded_non_positive_float: confloat(ge=-1.0, le=0.0) | None = Field(
            None, description='NonPositiveFloat with additional lower bound'
        )
        plain_constrained_int: conint(ge=5, le=100) | None = Field(
            None, description='No zero bound: should remain conint/Field'
        )
    ```

    <!-- fmt: on -->

---

## `--use-object-type` {#use-object-type}

Use object instead of Any for unspecified object and array values.

The `--use-object-type` flag configures the code generation to use `object`
instead of `Any` when JSON Schema does not define object properties or array
item schemas. This helps generate stricter type hints for unstructured values.

**Related:** [`--output-model-type`](model-customization.md#output-model-type), [`--target-python-version`](model-customization.md#target-python-version)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_object_type.json --output-model-type typing.TypedDict --target-python-version 3.10 --use-object-type # (1)!
    ```

    1. :material-arrow-left: `--use-object-type` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Payload",
      "type": "object",
      "properties": {
        "metadata": {
          "type": "object"
        },
        "items": {
          "type": "array"
        },
        "nested": {
          "type": "array",
          "items": {
            "type": "object"
          }
        }
      },
      "required": ["metadata", "items", "nested"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  use_object_type.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import TypedDict


    class Payload(TypedDict):
        metadata: dict[str, object]
        items: list[object]
        nested: list[dict[str, object]]
    ```

    <!-- fmt: on -->

---

## `--use-pendulum` {#use-pendulum}

Use pendulum types for date, time, and duration fields.

The `--use-pendulum` flag maps schema `date`, `time`, and `duration` values to
Pendulum types such as `pendulum.Date`, `pendulum.Time`, and `pendulum.Duration`.
`date-time` fields continue to use `pydantic.AwareDatetime`.

If you need a different datetime class for `date-time` fields, use
[`--output-datetime-class`](#output-datetime-class).

**See also:** [Type Mappings and Custom Types](../type-mappings.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_pendulum.json --use-pendulum # (1)!
    ```

    1. :material-arrow-left: `--use-pendulum` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Event",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "created_at": {
          "type": "string",
          "format": "date-time"
        },
        "event_date": {
          "type": "string",
          "format": "date"
        },
        "duration": {
          "type": "string",
          "format": "duration"
        }
      },
      "required": ["name", "created_at"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  use_pendulum.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pendulum import Date, Duration
    from pydantic import AwareDatetime, BaseModel


    class Event(BaseModel):
        name: str
        created_at: AwareDatetime
        event_date: Date | None = None
        duration: Duration | None = None
    ```

    <!-- fmt: on -->

---

## `--use-root-model-type-alias` {#use-root-model-type-alias}

Generate RootModel as type alias format for better mypy support.

When enabled, root models with simple types are generated as type aliases
instead of class definitions, improving mypy type inference.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input root_model_type_alias.json --use-root-model-type-alias --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--use-root-model-type-alias` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "Pet": {
          "type": "object",
          "properties": {
            "name": {"type": "string"}
          }
        },
        "Pets": {
          "oneOf": [
            {"$ref": "#/definitions/Pet"},
            {"type": "array", "items": {"$ref": "#/definitions/Pet"}}
          ]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  root_model_type_alias.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, RootModel

    Model = RootModel[Any]


    class Pet(BaseModel):
        name: str | None = None


    Pets = RootModel[Pet | list[Pet]]
    ```

    <!-- fmt: on -->

---

## `--use-specialized-enum` {#use-specialized-enum}

Generate StrEnum/IntEnum for string/integer enums (Python 3.11+).

The `--use-specialized-enum` flag generates specialized enum types:
- `StrEnum` for string enums
- `IntEnum` for integer enums

This is the default behavior for Python 3.11+ targets.

**Related:** [`--no-use-specialized-enum`](#no-use-specialized-enum), [`--use-subclass-enum`](model-customization.md#use-subclass-enum)

**Option relationships:**

- **Requires:** [`--target-python-version`](model-customization.md#target-python-version) = `3.11+` - `--use-specialized-enum` requires `--target-python-version` 3.11 or higher.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input subclass_enum.json --target-python-version 3.11 --use-specialized-enum # (1)!
    ```

    1. :material-arrow-left: `--use-specialized-enum` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "IntEnum": {
          "type": "integer",
          "enum": [
            1,
            2,
            3
          ]
        },
        "FloatEnum": {
          "type": "number",
          "enum": [
            1.1,
            2.1,
            3.1
          ]
        },
        "StrEnum": {
          "type": "string",
          "enum": [
            "1",
            "2",
            "3"
          ]
        },
        "NonTypedEnum": {
          "enum": [
            "1",
            "2",
            "3"
          ]
        },
        "BooleanEnum": {
          "type": "boolean",
          "enum": [
            true,
            false
          ]
        },
        "UnknownEnum": {
          "type": "unknown",
          "enum": [
            "a",
            "b"
          ]
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  subclass_enum.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum, IntEnum, StrEnum

    from pydantic import BaseModel, Field


    class IntEnumModel(IntEnum):
        integer_1 = 1
        integer_2 = 2
        integer_3 = 3


    class FloatEnum(Enum):
        number_1_1 = 1.1
        number_2_1 = 2.1
        number_3_1 = 3.1


    class StrEnumModel(StrEnum):
        field_1 = '1'
        field_2 = '2'
        field_3 = '3'


    class NonTypedEnum(Enum):
        field_1 = '1'
        field_2 = '2'
        field_3 = '3'


    class BooleanEnum(Enum):
        boolean_True = True
        boolean_False = False


    class UnknownEnum(Enum):
        a = 'a'
        b = 'b'


    class Model(BaseModel):
        IntEnum: IntEnumModel | None = None
        FloatEnum_1: FloatEnum | None = Field(None, alias='FloatEnum')
        StrEnum: StrEnumModel | None = None
        NonTypedEnum_1: NonTypedEnum | None = Field(None, alias='NonTypedEnum')
        BooleanEnum_1: BooleanEnum | None = Field(None, alias='BooleanEnum')
        UnknownEnum_1: UnknownEnum | None = Field(None, alias='UnknownEnum')
    ```

    <!-- fmt: on -->

---

## `--use-standard-collections` {#use-standard-collections}

Use built-in dict/list instead of typing.Dict/List.

The `--use-standard-collections` flag generates built-in container types
(dict, list) instead of typing module equivalents. This produces cleaner
code for Python 3.10+ where built-in types support subscripting.

**Related:** [`--use-generic-container-types`](#use-generic-container-types)

**See also:** [Python Version Compatibility](../python-version-compatibility.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input root_model_with_additional_properties.json --use-standard-collections # (1)!
    ```

    1. :material-arrow-left: `--use-standard-collections` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$id": "test.json",
      "description": "test",
      "type": "object",
      "required": [
        "test_id",
        "test_ip",
        "result",
        "nested_object_result",
        "nested_enum_result"
      ],
      "properties": {
        "test_id": {
          "type": "string",
          "description": "test ID"
        },
        "test_ip": {
          "type": "string",
          "description": "test IP"
        },
        "result": {
          "type": "object",
          "additionalProperties": {
            "type": "integer"
          }
        },
        "nested_object_result": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "status":{
                "type": "integer"
              }
            },
            "required": ["status"]
          }
        },
        "nested_enum_result": {
          "type": "object",
          "additionalProperties": {
            "enum": ["red", "green"]
          }
        },
        "all_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "allOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "one_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "oneOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "any_of_result" :{
          "type" : "object",
          "additionalProperties" :
          {
            "anyOf" : [
              { "$ref" : "#/definitions/User" },
              { "type" : "object",
                "properties": {
                  "description": {"type" : "string" }
                }
              }
            ]
          }
        },
        "all_of_with_unknown_object" :{
          "type" : "object",
          "additionalProperties" :
          {
            "allOf" : [
              { "$ref" : "#/definitions/User" },
              { "description": "TODO" }
            ]
          }
        },
        "objectRef": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/User"
          }
        },
        "deepNestedObjectRef": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                 "$ref": "#/definitions/User"
              }
            }
          }
        }
      },
      "definitions": {
        "User": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  root_model_with_additional_properties.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from enum import Enum

    from pydantic import BaseModel, Field


    class NestedObjectResult(BaseModel):
        status: int


    class NestedEnumResult(Enum):
        red = 'red'
        green = 'green'


    class OneOfResult(BaseModel):
        description: str | None = None


    class AnyOfResult(BaseModel):
        description: str | None = None


    class User(BaseModel):
        name: str | None = None


    class AllOfResult(User):
        description: str | None = None


    class Model(BaseModel):
        test_id: str = Field(..., description='test ID')
        test_ip: str = Field(..., description='test IP')
        result: dict[str, int]
        nested_object_result: dict[str, NestedObjectResult]
        nested_enum_result: dict[str, NestedEnumResult]
        all_of_result: dict[str, AllOfResult] | None = None
        one_of_result: dict[str, User | OneOfResult] | None = None
        any_of_result: dict[str, User | AnyOfResult] | None = None
        all_of_with_unknown_object: dict[str, User] | None = None
        objectRef: dict[str, User] | None = None
        deepNestedObjectRef: dict[str, dict[str, dict[str, User]]] | None = None
    ```

    <!-- fmt: on -->

---

## `--use-standard-primitive-types` {#use-standard-primitive-types}

Use Python standard library types for string formats instead of str.

The `--use-standard-primitive-types` flag configures the code generation to use
Python standard library types (UUID, IPv4Address, IPv6Address, Path) for corresponding
string formats instead of plain str. This affects dataclass, msgspec, and TypedDict
output types. Pydantic already uses these types by default.

**Related:** [`--output-datetime-class`](#output-datetime-class), [`--output-model-type`](model-customization.md#output-model-type)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_standard_primitive_types.json --output-model-type dataclasses.dataclass --use-standard-primitive-types # (1)!
    ```

    1. :material-arrow-left: `--use-standard-primitive-types` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid"
        },
        "ip_address": {
          "type": "string",
          "format": "ipv4"
        },
        "config_path": {
          "type": "string",
          "format": "path"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  use_standard_primitive_types.json

    from __future__ import annotations

    from dataclasses import dataclass
    from ipaddress import IPv4Address
    from pathlib import Path
    from uuid import UUID


    @dataclass
    class Model:
        id: UUID | None = None
        ip_address: IPv4Address | None = None
        config_path: Path | None = None
    ```

    <!-- fmt: on -->

---

## `--use-total-false-for-typed-dict` {#use-total-false-for-typed-dict}

Generate TypedDict declarations with `total=False`.

Optional fields are left unwrapped, while required fields are marked with
`Required[...]`. This can substantially reduce generated code when most fields
are optional.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_total_false_for_typed_dict.json --output-model-type typing.TypedDict --use-total-false-for-typed-dict --use-frozen-field # (1)!
    ```

    1. :material-arrow-left: `--use-total-false-for-typed-dict` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "$defs": {
        "ClassModel": {
          "type": "object",
          "properties": {
            "required_value": {
              "type": "string"
            },
            "optional_value": {
              "type": "integer"
            },
            "required_read_only": {
              "type": "boolean",
              "readOnly": true
            },
            "optional_read_only": {
              "type": "number",
              "readOnly": true
            }
          },
          "required": [
            "required_value",
            "required_read_only"
          ]
        },
        "BaseModel": {
          "type": "object",
          "properties": {
            "base_required": {
              "type": "string"
            },
            "base_optional": {
              "type": "integer"
            }
          },
          "required": [
            "base_required"
          ]
        },
        "FunctionalModel": {
          "allOf": [
            {
              "$ref": "#/$defs/BaseModel"
            },
            {
              "type": "object",
              "properties": {
                "invalid-key": {
                  "type": "string"
                },
                "child_optional": {
                  "type": "boolean"
                }
              },
              "required": [
                "invalid-key"
              ]
            }
          ]
        },
        "ClosedModel": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "closed_required": {
              "type": "string"
            },
            "closed_optional": {
              "type": "integer"
            }
          },
          "required": [
            "closed_required"
          ]
        },
        "ExtraItemsModel": {
          "type": "object",
          "additionalProperties": {
            "type": "integer"
          },
          "properties": {
            "extra_required": {
              "type": "string"
            },
            "extra_optional": {
              "type": "boolean"
            }
          },
          "required": [
            "extra_required"
          ]
        }
      },
      "type": "object",
      "properties": {
        "class_model": {
          "$ref": "#/$defs/ClassModel"
        },
        "functional_model": {
          "$ref": "#/$defs/FunctionalModel"
        },
        "closed_model": {
          "$ref": "#/$defs/ClosedModel"
        },
        "extra_items_model": {
          "$ref": "#/$defs/ExtraItemsModel"
        }
      },
      "required": [
        "class_model"
      ]
    }
    ```

    **Output:**

    === "Python 3.10"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  use_total_false_for_typed_dict.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing_extensions import ReadOnly, Required, TypedDict


        class ClassModel(TypedDict, total=False):
            required_value: Required[str]
            optional_value: int
            required_read_only: Required[ReadOnly[bool]]
            optional_read_only: ReadOnly[float]


        class BaseModel(TypedDict, total=False):
            base_required: Required[str]
            base_optional: int


        FunctionalModel = TypedDict(
            'FunctionalModel',
            {
                'base_required': Required[str],
                'base_optional': int,
                'invalid-key': Required[str],
                'child_optional': bool,
            },
            total=False,
        )


        class ClosedModel(TypedDict, total=False, closed=True):
            closed_required: Required[str]
            closed_optional: int


        class ExtraItemsModel(TypedDict, total=False, extra_items=int):
            extra_required: Required[str]
            extra_optional: bool


        class Model(TypedDict, total=False):
            class_model: Required[ClassModel]
            functional_model: FunctionalModel
            closed_model: ClosedModel
            extra_items_model: ExtraItemsModel
        ```

        <!-- fmt: on -->

    === "Python 3.11"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  use_total_false_for_typed_dict.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Required

        from typing_extensions import ReadOnly, TypedDict


        class ClassModel(TypedDict, total=False):
            required_value: Required[str]
            optional_value: int
            required_read_only: Required[ReadOnly[bool]]
            optional_read_only: ReadOnly[float]


        class BaseModel(TypedDict, total=False):
            base_required: Required[str]
            base_optional: int


        FunctionalModel = TypedDict(
            'FunctionalModel',
            {
                'base_required': Required[str],
                'base_optional': int,
                'invalid-key': Required[str],
                'child_optional': bool,
            },
            total=False,
        )


        class ClosedModel(TypedDict, total=False, closed=True):
            closed_required: Required[str]
            closed_optional: int


        class ExtraItemsModel(TypedDict, total=False, extra_items=int):
            extra_required: Required[str]
            extra_optional: bool


        class Model(TypedDict, total=False):
            class_model: Required[ClassModel]
            functional_model: FunctionalModel
            closed_model: ClosedModel
            extra_items_model: ExtraItemsModel
        ```

        <!-- fmt: on -->

---

## `--use-tuple-for-fixed-items` {#use-tuple-for-fixed-items}

Generate tuple types for arrays with items array syntax.

When `--use-tuple-for-fixed-items` is enabled and an array has `items` as an array
with `minItems == maxItems == len(items)`, generate a tuple type instead of a list.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input items_array_tuple.json --use-tuple-for-fixed-items # (1)!
    ```

    1. :material-arrow-left: `--use-tuple-for-fixed-items` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "https://json-schema.org/draft-07/schema",
      "type": "object",
      "properties": {
        "point": {
          "type": "array",
          "items": [{"type": "number"}, {"type": "number"}],
          "minItems": 2,
          "maxItems": 2
        }
      },
      "required": ["point"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  items_array_tuple.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Model(BaseModel):
        point: tuple[float, float]
    ```

    <!-- fmt: on -->

---

## `--use-tuple-for-fixed-length-arrays` {#use-tuple-for-fixed-length-arrays}

Generate tuple types for homogeneous fixed-length arrays.

When `--use-tuple-for-fixed-length-arrays` is enabled and an array has one
`items` schema with `minItems == maxItems`, generate a tuple type instead of a
list. An empty fixed-length array becomes `tuple[()]`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input fixed_length_array_tuples.yaml --use-tuple-for-fixed-length-arrays --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--use-tuple-for-fixed-length-arrays` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.0.3
    info:
      title: Fixed length array tuples
      version: 1.0.0
    paths: {}
    components:
      schemas:
        FixedLengthArrayTuples:
          type: object
          required:
            - vector
            - allOfVector
            - allOfEmpty
            - empty
            - inlineObject
            - refValues
            - range
            - minimumOnly
          properties:
            vector:
              type: array
              minItems: 3
              maxItems: 3
              items:
                type: number
                format: double
            allOfVector:
              allOf:
                - type: array
                  minItems: 2
                  maxItems: 2
                  items:
                    type: string
            allOfEmpty:
              allOf:
                - type: array
                  minItems: 0
                  maxItems: 0
                  items:
                    type: string
            empty:
              type: array
              minItems: 0
              maxItems: 0
              items:
                type: number
                format: double
            inlineObject:
              type: array
              minItems: 2
              maxItems: 2
              items:
                type: object
                required:
                  - value
                properties:
                  value:
                    type: string
            refValues:
              type: array
              minItems: 3
              maxItems: 3
              items:
                $ref: '#/components/schemas/RefValue'
            range:
              type: array
              minItems: 2
              maxItems: 4
              items:
                type: integer
            minimumOnly:
              type: array
              minItems: 3
              items:
                type: string
        RefValue:
          type: object
          required:
            - id
          properties:
            id:
              type: integer
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  fixed_length_array_tuples.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field, RootModel


    class AllOfVector(RootModel[tuple[str, str]]):
        root: tuple[str, str]


    class AllOfEmpty(RootModel[tuple[()]]):
        root: tuple[()]


    class InlineObjectItem(BaseModel):
        value: str


    class RefValue(BaseModel):
        id: int


    class FixedLengthArrayTuples(BaseModel):
        vector: tuple[float, float, float]
        allOfVector: AllOfVector
        allOfEmpty: AllOfEmpty
        empty: tuple[()]
        inlineObject: tuple[InlineObjectItem, InlineObjectItem]
        refValues: tuple[RefValue, RefValue, RefValue]
        range: list[int] = Field(..., max_length=4, min_length=2)
        minimumOnly: list[str] = Field(..., min_length=3)
    ```

    <!-- fmt: on -->

---

## `--use-type-alias` {#use-type-alias}

Use TypeAlias instead of root models for type definitions (experimental).

The `--use-type-alias` flag generates TypeAlias declarations instead of
root model classes for certain type definitions. For Python 3.10-3.11, it
generates TypeAliasType, and for Python 3.12+, it uses the 'type' statement
syntax. This feature is experimental.

**Related:** [`--target-python-version`](model-customization.md#target-python-version)

**See also:** [Model Reuse and Deduplication](../model-reuse.md), [Root Models and Type Aliases](../root-model-and-type-alias.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input type_alias.graphql --use-type-alias # (1)!
    ```

    1. :material-arrow-left: `--use-type-alias` - the option documented here

??? example "Examples"

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "definitions": {
            "SimpleString": {
              "type": "string"
            },
            "UnionType": {
              "anyOf": [
                {"type": "string"},
                {"type": "integer"}
              ]
            },
            "ArrayType": {
              "type": "array",
              "items": {"type": "string"}
            },
            "AnnotatedType": {
              "title": "MyAnnotatedType",
              "description": "An annotated union type",
              "anyOf": [
                {"type": "string"},
                {"type": "boolean"}
              ]
            },
            "ModelWithTypeAliasField": {
              "type": "object",
              "properties": {
                "simple_field": {"$ref": "#/definitions/SimpleString"},
                "union_field": {"$ref": "#/definitions/UnionType"},
                "array_field": {"$ref": "#/definitions/ArrayType"},
                "annotated_field": {"$ref": "#/definitions/AnnotatedType"}
              }
            }
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  type_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Annotated, Any

        from pydantic import BaseModel, Field
        from typing_extensions import TypeAliasType

        Model = TypeAliasType("Model", Any)


        SimpleString = TypeAliasType("SimpleString", str)


        UnionType = TypeAliasType("UnionType", str | int)


        ArrayType = TypeAliasType("ArrayType", list[str])


        AnnotatedType = TypeAliasType(
            "AnnotatedType",
            Annotated[
                str | bool,
                Field(..., description='An annotated union type', title='MyAnnotatedType'),
            ],
        )


        class ModelWithTypeAliasField(BaseModel):
            simple_field: SimpleString | None = None
            union_field: UnionType | None = None
            array_field: ArrayType | None = None
            annotated_field: AnnotatedType | None = None
        ```

        <!-- fmt: on -->

    === "GraphQL"

        **Input Schema:**

        ```graphql
        scalar SimpleString

        type Person {
          name: String!
          age: Int!
        }

        type Pet {
          name: String!
          type: String!
        }

        union UnionType = Person | Pet

        type ModelWithTypeAliasField {
          simple_field: SimpleString
          union_field: UnionType
          string_field: String
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  type_alias.graphql
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Literal, Union

        from pydantic import BaseModel, Field
        from typing_extensions import TypeAliasType

        Boolean = TypeAliasType("Boolean", bool)
        """
        The `Boolean` scalar type represents `true` or `false`.
        """


        Int = TypeAliasType("Int", int)
        """
        The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
        """


        SimpleString = TypeAliasType("SimpleString", str)


        String = TypeAliasType("String", str)
        """
        The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
        """


        class Person(BaseModel):
            age: Int
            name: String
            typename__: Literal['Person'] | None = Field('Person', alias='__typename')


        class Pet(BaseModel):
            name: String
            type: String
            typename__: Literal['Pet'] | None = Field('Pet', alias='__typename')


        UnionType = TypeAliasType(
            "UnionType",
            Union[
                'Person',
                'Pet',
            ],
        )


        class ModelWithTypeAliasField(BaseModel):
            simple_field: SimpleString | None = None
            string_field: String | None = None
            union_field: UnionType | None = None
            typename__: Literal['ModelWithTypeAliasField'] | None = Field(
                'ModelWithTypeAliasField', alias='__typename'
            )
        ```

        <!-- fmt: on -->

---

## `--use-type-alias-type` {#use-type-alias-type}

Use runtime TypeAliasType objects for aliases before Python 3.12 (experimental).

The `--use-type-alias-type` flag implies `--use-type-alias` and forces
`TypeAliasType` for every output model type on Python 3.10-3.11. Python 3.12+
continues to use native `type` statements.

**See also:** [Root Models and Type Aliases](../root-model-and-type-alias.md)

**Option relationships:**

- **Implies:** [`--use-type-alias`](typing-customization.md#use-type-alias) enabled

!!! tip "Usage"

    ```bash
    datamodel-codegen --input type_alias.json --output-model-type typing.TypedDict --use-type-alias-type --target-python-version 3.10 # (1)!
    ```

    1. :material-arrow-left: `--use-type-alias-type` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "SimpleString": {
          "type": "string"
        },
        "UnionType": {
          "anyOf": [
            {"type": "string"},
            {"type": "integer"}
          ]
        },
        "ArrayType": {
          "type": "array",
          "items": {"type": "string"}
        },
        "AnnotatedType": {
          "title": "MyAnnotatedType",
          "description": "An annotated union type",
          "anyOf": [
            {"type": "string"},
            {"type": "boolean"}
          ]
        },
        "ModelWithTypeAliasField": {
          "type": "object",
          "properties": {
            "simple_field": {"$ref": "#/definitions/SimpleString"},
            "union_field": {"$ref": "#/definitions/UnionType"},
            "array_field": {"$ref": "#/definitions/ArrayType"},
            "annotated_field": {"$ref": "#/definitions/AnnotatedType"}
          }
        }
      }
    }
    ```

    **Output:**

    === "Python 3.10"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  type_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Any, TypedDict

        from typing_extensions import NotRequired, TypeAliasType

        Model = TypeAliasType("Model", Any)


        SimpleString = TypeAliasType("SimpleString", str)


        UnionType = TypeAliasType("UnionType", str | int)


        ArrayType = TypeAliasType("ArrayType", list[str])


        AnnotatedType = TypeAliasType("AnnotatedType", str | bool)


        class ModelWithTypeAliasField(TypedDict):
            simple_field: NotRequired[SimpleString]
            union_field: NotRequired[UnionType]
            array_field: NotRequired[ArrayType]
            annotated_field: NotRequired[AnnotatedType]
        ```

        <!-- fmt: on -->

    === "Python 3.12"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  type_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from typing import Any, NotRequired, TypedDict

        type Model = Any


        type SimpleString = str


        type UnionType = str | int


        type ArrayType = list[str]


        type AnnotatedType = str | bool


        class ModelWithTypeAliasField(TypedDict):
            simple_field: NotRequired[SimpleString]
            union_field: NotRequired[UnionType]
            array_field: NotRequired[ArrayType]
            annotated_field: NotRequired[AnnotatedType]
        ```

        <!-- fmt: on -->

---

## `--use-typed-nullable-map-values` {#use-typed-nullable-map-values}

Type the values of nullable maps as their schemas say instead of Any.

A nullable map here is a schema whose type array lists `object` alone or with `null`, such as
`type: [object, "null"]` or `type: [object]`, and that declares its values with `additionalProperties`. Without the
`--use-typed-nullable-map-values` flag the output keeps the 0.83.0 form, `dict[str, Any] | None`, or
`dict[str, Any]` when the type array has no `null`, whatever the values are. A map made nullable by `nullable: true`
and a map typed `type: object` keep their typed values either way.

With the flag the values follow their schema, such as `dict[str, int] | None` or `dict[str, Player] | None`, and an
object value gets a model named after the map, such as `Teams1` for the values of `Teams`. Those value models take
the names left free, so the other models keep their 0.83.0 names, and options keyed by class name, such as
`--base-class-map` or `--aliases`, apply to the final names. Typed values change more than the maps themselves:
`--reuse-model` makes a value model and the models equal to it one model, which can leave out a schema's class, and
no longer makes nullable maps with different values subclasses of each other, and `--collapse-root-models` collapses
the root models that the values use. When typing the values would change the modules written, the values of the
whole run stay untyped.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input nullable_map_value_types.yaml --use-typed-nullable-map-values --output-model-type pydantic_v2.BaseModel # (1)!
    ```

    1. :material-arrow-left: `--use-typed-nullable-map-values` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Nullable map value types
      version: "1.0"
    paths:
      /scores:
        get:
          operationId: listScores
          parameters:
            - name: players
              in: query
              schema:
                type: [object, "null"]
                additionalProperties:
                  $ref: "#/components/schemas/Player"
          responses:
            "200":
              description: The scores.
        post:
          operationId: replaceScores
          requestBody:
            content:
              application/json:
                schema:
                  type: [object, "null"]
                  additionalProperties:
                    type: integer
          responses:
            "200":
              description: The stored scores.
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Scores"
    components:
      schemas:
        Player:
          type: object
          properties:
            name:
              type: string
        Scores:
          type: [object, "null"]
          additionalProperties:
            type: integer
        NullFirstScores:
          type: ["null", object]
          additionalProperties:
            type: integer
        ObjectOnlyScores:
          type: [object]
          additionalProperties:
            type: integer
        Players:
          type: [object, "null"]
          additionalProperties:
            $ref: "#/components/schemas/Player"
        Teams:
          type: [object, "null"]
          additionalProperties:
            type: object
            properties:
              captain:
                $ref: "#/components/schemas/Player"
        Rounds:
          type: [object, "null"]
          additionalProperties:
            type: array
            items:
              type: integer
        Seasons:
          type: [object, "null"]
          additionalProperties:
            type: [object, "null"]
            additionalProperties:
              type: number
        Labels:
          type: [object, "null"]
          additionalProperties:
            type: string
            minLength: 1
        Board:
          type: object
          required:
            - scores
          properties:
            scores:
              type: [object, "null"]
              additionalProperties:
                type: integer
            players:
              type: [object, "null"]
              additionalProperties:
                $ref: "#/components/schemas/Player"
            teams:
              type: [object, "null"]
              additionalProperties:
                type: object
                properties:
                  captain:
                    $ref: "#/components/schemas/Player"
            history:
              type: array
              items:
                type: [object, "null"]
                additionalProperties:
                  type: integer
            plain:
              type: object
              additionalProperties:
                type: integer
            nullable_array:
              type: [array, "null"]
              items:
                type: integer
            untyped:
              type: [object, "null"]
              additionalProperties: true
            fixed:
              type: [object, "null"]
              additionalProperties:
                type: integer
              const:
                x: 1
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  nullable_map_value_types.yaml

        from __future__ import annotations

        from typing import Any

        from pydantic import BaseModel, RootModel, constr


        class Player(BaseModel):
            name: str | None = None


        class Scores(RootModel[dict[str, int] | None]):
            root: dict[str, int] | None


        class NullFirstScores(RootModel[dict[str, int] | None]):
            root: dict[str, int] | None


        class ObjectOnlyScores(RootModel[dict[str, int]]):
            root: dict[str, int]


        class Players(RootModel[dict[str, Player] | None]):
            root: dict[str, Player] | None


        class Teams1(BaseModel):
            captain: Player | None = None


        class Teams(RootModel[dict[str, Teams1] | None]):
            root: dict[str, Teams1] | None


        class Rounds(RootModel[dict[str, list[int]] | None]):
            root: dict[str, list[int]] | None


        class Seasons(RootModel[dict[str, dict[str, float] | None] | None]):
            root: dict[str, dict[str, float] | None] | None


        class Labels(RootModel[dict[str, constr(min_length=1)] | None]):
            root: dict[str, constr(min_length=1)] | None


        class Teams2(BaseModel):
            captain: Player | None = None


        class Board(BaseModel):
            scores: dict[str, int] | None
            players: dict[str, Player] | None = None
            teams: dict[str, Teams2] | None = None
            history: list[dict[str, int] | None] | None = None
            plain: dict[str, int] | None = None
            nullable_array: list[int] | None = None
            untyped: dict[str, Any] | None = None
            fixed: dict[str, int] = None
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  nullable_map_value_types.yaml

        from __future__ import annotations

        from typing import Any

        from pydantic import BaseModel, RootModel


        class Player(BaseModel):
            name: str | None = None


        class Scores(RootModel[dict[str, Any] | None]):
            root: dict[str, Any] | None


        class NullFirstScores(RootModel[dict[str, Any] | None]):
            root: dict[str, Any] | None


        class ObjectOnlyScores(RootModel[dict[str, Any]]):
            root: dict[str, Any]


        class Players(RootModel[dict[str, Any] | None]):
            root: dict[str, Any] | None


        class Teams(RootModel[dict[str, Any] | None]):
            root: dict[str, Any] | None


        class Rounds(RootModel[dict[str, Any] | None]):
            root: dict[str, Any] | None


        class Seasons(RootModel[dict[str, Any] | None]):
            root: dict[str, Any] | None


        class Labels(RootModel[dict[str, Any] | None]):
            root: dict[str, Any] | None


        class Board(BaseModel):
            scores: dict[str, Any] | None
            players: dict[str, Any] | None = None
            teams: dict[str, Any] | None = None
            history: list[dict[str, Any] | None] | None = None
            plain: dict[str, int] | None = None
            nullable_array: list[int] | None = None
            untyped: dict[str, Any] | None = None
            fixed: dict[str, int] = None
        ```

        <!-- fmt: on -->

---

## `--use-union-operator` {#use-union-operator}

Use | operator for Union types (PEP 604).

The `--use-union-operator` flag generates union types using the | operator
(e.g., `str | None`) instead of `Union[str, None]` or `Optional[str]`.
This is the default behavior.

**Related:** [`--no-use-union-operator`](#no-use-union-operator)

**See also:** [Python Version Compatibility](../python-version-compatibility.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input annotated.graphql --output-model-type pydantic_v2.BaseModel --use-annotated --use-union-operator # (1)!
    ```

    1. :material-arrow-left: `--use-union-operator` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    type A {
        field: String!
        optionalField: String
        listField: [String!]!
        listOptionalField: [String]!
        optionalListField: [String!]
        optionalListOptionalField: [String]
        listListField:[[String!]!]!
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  annotated.graphql
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Annotated, Literal

    from pydantic import BaseModel, Field
    from typing_extensions import TypeAliasType

    Boolean = TypeAliasType("Boolean", bool)
    """
    The `Boolean` scalar type represents `true` or `false`.
    """


    String = TypeAliasType("String", str)
    """
    The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
    """


    class A(BaseModel):
        field: String
        listField: list[String]
        listListField: list[list[String]]
        listOptionalField: list[String | None]
        optionalField: String | None = None
        optionalListField: list[String] | None = None
        optionalListOptionalField: list[String | None] | None = None
        typename__: Annotated[Literal['A'] | None, Field(alias='__typename')] = 'A'
    ```

    <!-- fmt: on -->

---

## `--use-unique-items-as-set` {#use-unique-items-as-set}

Generate set types for arrays with uniqueItems constraint.

The `--use-unique-items-as-set` flag generates Python set types instead of
list types for JSON Schema arrays that have the uniqueItems constraint set
to true, enforcing uniqueness at the type level.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api_constrained.yaml --use-unique-items-as-set --field-constraints # (1)!
    ```

    1. :material-arrow-left: `--use-unique-items-as-set` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
                minimum: 0
                maximum: 100
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              minimum: 0
              maximum: 9223372036854775807
            name:
              type: string
              maxLength: 256
            tag:
              type: string
              maxLength: 64
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
          maxItems: 10
          minItems: 1
          uniqueItems: true
        UID:
          type: integer
          minimum: 0
        Users:
          type: array
          items:
            required:
              - id
              - name
              - uid
            properties:
              id:
                type: integer
                format: int64
                minimum: 0
              name:
                type: string
                maxLength: 256
              tag:
                type: string
                maxLength: 64
              uid:
                $ref: '#/components/schemas/UID'
              phones:
                type: array
                items:
                  type: string
                  minLength: 3
                maxItems: 10
              fax:
                type: array
                items:
                  type: string
                  minLength: 3
              height:
                type:
                  - integer
                  - number
                minimum: 1
                maximum: 300
              weight:
                type:
                  - number
                  - integer
                minimum: 1.0
                maximum: 1000.0
              age:
                type: integer
                minimum: 0.0
                maximum: 200.0
                exclusiveMinimum: true
              rating:
                type: number
                minimum: 0
                exclusiveMinimum: true
                maximum: 5

        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                minLength: 1
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api_constrained.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field


    class Pet(BaseModel):
        id: int = Field(..., ge=0, le=9223372036854775807)
        name: str = Field(..., max_length=256)
        tag: str | None = Field(None, max_length=64)


    class Pets(BaseModel):
        __root__: set[Pet] = Field(..., max_items=10, min_items=1, unique_items=True)


    class UID(BaseModel):
        __root__: int = Field(..., ge=0)


    class Phone(BaseModel):
        __root__: str = Field(..., min_length=3)


    class FaxItem(BaseModel):
        __root__: str = Field(..., min_length=3)


    class User(BaseModel):
        id: int = Field(..., ge=0)
        name: str = Field(..., max_length=256)
        tag: str | None = Field(None, max_length=64)
        uid: UID
        phones: list[Phone] | None = Field(None, max_items=10)
        fax: list[FaxItem] | None = None
        height: int | float | None = Field(None, ge=1.0, le=300.0)
        weight: float | int | None = Field(None, ge=1.0, le=1000.0)
        age: int | None = Field(None, gt=0, le=200)
        rating: float | None = Field(None, gt=0.0, le=5.0)


    class Users(BaseModel):
        __root__: list[User]


    class Id(BaseModel):
        __root__: str


    class Rules(BaseModel):
        __root__: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(BaseModel):
        __root__: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

---

# Template Customization

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/template-customization/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--additional-imports`](#additional-imports) | Add custom imports to generated output files. |
| [`--class-decorators`](#class-decorators) | Add custom decorators to generated model classes. |
| [`--custom-file-header`](#custom-file-header) | Add custom header text to the generated file. |
| [`--custom-file-header-mode`](#custom-file-header-mode) | Choose how a custom file header combines with generated prov... |
| [`--custom-file-header-path`](#custom-file-header-path) | Add custom header content from file to generated code. |
| [`--custom-formatters`](#custom-formatters) | Apply custom Python code formatters to generated output. |
| [`--custom-formatters-kwargs`](#custom-formatters-kwargs) | Pass custom arguments to custom formatters via inline JSON o... |
| [`--custom-template-dir`](#custom-template-dir) | Use custom Jinja2 templates for model generation. |
| [`--disable-appending-item-suffix`](#disable-appending-item-suffix) | Disable appending 'Item' suffix to array item types. |
| [`--disable-timestamp`](#disable-timestamp) | Disable timestamp in generated file header for reproducible ... |
| [`--enable-command-header`](#enable-command-header) | Include command-line options in file header for reproducibil... |
| [`--enable-generated-header-marker`](#enable-generated-header-marker) | Include the @generated marker in file header for generated-c... |
| [`--enable-version-header`](#enable-version-header) | Include tool version information in file header. |
| [`--extra-template-data`](#extra-template-data) | Pass custom template variables via inline JSON or a JSON fil... |
| [`--formatters`](#formatters) | Specify code formatters to apply to generated output. |
| [`--generate-schema-validators`](#generate-schema-validators) | Generate experimental Pydantic v2 model validators for JSON ... |
| [`--no-treat-dot-as-module`](#no-treat-dot-as-module) | Keep dots in schema names as underscores for flat output. |
| [`--no-use-type-checking-imports`](#no-use-type-checking-imports) | Keep generated model imports available at runtime when using... |
| [`--schema-validator-base-class-name`](#schema-validator-base-class-name) | Set the generated shared Pydantic v2 schema runtime validato... |
| [`--schema-validator-type`](#schema-validator-type) | Select the schema-derived runtime validator backend. |
| [`--strict-dotted-module-names`](#strict-dotted-module-names) | Require canonical Python identifiers when inferring dotted m... |
| [`--treat-dot-as-module`](#treat-dot-as-module) | Treat dots in schema names as module separators. |
| [`--use-double-quotes`](#use-double-quotes) | Use double quotes for string literals in generated code. |
| [`--use-exact-imports`](#use-exact-imports) | Import exact types instead of modules. |
| [`--use-type-checking-imports`](#use-type-checking-imports) | Allow Ruff to move typing-only imports into TYPE_CHECKING bl... |
| [`--validators`](#validators) | Add custom field validators to generated Pydantic v2 models. |
| [`--wrap-string-literal`](#wrap-string-literal) | Wrap long string literals across multiple lines. |

---

## 🍳 Recipes

### Control generated file headers

Choose a header source and remove volatile timestamp content for reproducible output.

**Options:** [`--custom-file-header`](#custom-file-header), [`--custom-file-header-path`](#custom-file-header-path), [`--disable-timestamp`](#disable-timestamp)

### Inject project-specific code

Add imports, decorators, or custom templates when generated classes must fit local framework conventions.

**Options:** [`--additional-imports`](#additional-imports), [`--class-decorators`](#class-decorators), [`--custom-template-dir`](#custom-template-dir)

---

## `--additional-imports` {#additional-imports}

Add custom imports to generated output files.

The `--additional-imports` flag allows you to specify custom imports as a
comma-delimited list that will be added to the generated output file. This
is useful when using custom types defined in external modules (e.g.,
"datetime.datetime,datetime.date,mymodule.myclass.MyCustomPythonClass").

**See also:** [Custom Class Decorators](../class-decorators.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input additional-imports.graphql --additional-imports datetime.datetime,datetime.date,mymodule.myclass.MyCustomPythonClass # (1)!
    ```

    1. :material-arrow-left: `--additional-imports` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    scalar Date

    "DateTime (ISO8601, example: 2020-01-01T10:11:12+00:00)"
    scalar DateTime

    scalar MyCustomClass

    type A {
      a: Date!
      b: DateTime!
      c: MyCustomClass!
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  additional-imports.graphql
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from datetime import date, datetime
    from typing import Literal

    from mymodule.myclass import MyCustomPythonClass
    from pydantic import BaseModel, Field
    from typing_extensions import TypeAliasType

    Boolean = TypeAliasType("Boolean", bool)
    """
    The `Boolean` scalar type represents `true` or `false`.
    """


    Date = TypeAliasType("Date", date)


    DateTime = TypeAliasType("DateTime", datetime)
    """
    DateTime (ISO8601, example: 2020-01-01T10:11:12+00:00)
    """


    MyCustomClass = TypeAliasType("MyCustomClass", MyCustomPythonClass)


    String = TypeAliasType("String", str)
    """
    The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
    """


    class A(BaseModel):
        a: Date
        b: DateTime
        c: MyCustomClass
        typename__: Literal['A'] | None = Field('A', alias='__typename')
    ```

    <!-- fmt: on -->

---

## `--class-decorators` {#class-decorators}

Add custom decorators to generated model classes.

The `--class-decorators` option adds custom decorators to all generated model classes.
This is useful for integrating with serialization libraries like `dataclasses_json`.

Use with `--additional-imports` to add the required imports for the decorators.
The `@` prefix is optional and will be added automatically if missing.

**Related:** [`--additional-imports`](#additional-imports), [`--output-model-type`](model-customization.md#output-model-type)

**See also:** [Custom Class Decorators](../class-decorators.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input simple_frozen_test.json --output-model-type dataclasses.dataclass --class-decorators @dataclass_json --additional-imports dataclasses_json.dataclass_json # (1)!
    ```

    1. :material-arrow-left: `--class-decorators` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "title": "User",
      "properties": {
        "name": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        },
        "email": {
          "type": "string",
          "format": "email"
        }
      },
      "required": ["name", "age"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  simple_frozen_test.json
    #   timestamp: 1985-10-26T08:21:00+00:00

    from __future__ import annotations

    from dataclasses import dataclass

    from dataclasses_json import dataclass_json


    @dataclass_json
    @dataclass
    class User:
        name: str
        age: int
        email: str | None = None
    ```

    <!-- fmt: on -->

---

## `--custom-file-header` {#custom-file-header}

Add custom header text to the generated file.

The `--custom-file-header` flag replaces the default "generated by datamodel-codegen"
header with custom text. This is useful for adding copyright notices, license
headers, or other metadata to generated files.

**Option relationships:**

- **Conflicts:** [`--custom-file-header-path`](template-customization.md#custom-file-header-path) - `--custom-file-header` can not be used with `--custom-file-header-path`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input no_alias.json --custom-file-header "# Copyright 2024 MyCompany" # (1)!
    ```

    1. :material-arrow-left: `--custom-file-header` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "first-name": {
          "type": "string"
        },
        "last-name": {
          "type": "string"
        },
        "email_address": {
          "type": "string"
        }
      },
      "required": ["first-name", "last-name"]
    }
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # Copyright 2024 MyCompany

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Person(BaseModel):
            first_name: str = Field(..., alias='first-name')
            last_name: str = Field(..., alias='last-name')
            email_address: str | None = None
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  no_alias.json
        #   timestamp: 2019-07-26T00:00:00+00:00

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Person(BaseModel):
            first_name: str = Field(..., alias='first-name')
            last_name: str = Field(..., alias='last-name')
            email_address: str | None = None
        ```

        <!-- fmt: on -->

---

## `--custom-file-header-mode` {#custom-file-header-mode}

Choose how a custom file header combines with generated provenance.

The `prepend` mode places a license or copyright header before the generated filename,
timestamp, version, and command metadata. The default `replace` mode preserves existing behavior.

**Related:** [`--custom-file-header`](#custom-file-header), [`--custom-file-header-path`](#custom-file-header-path), [`--enable-version-header`](#enable-version-header)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input simple_string.json --custom-file-header "# Copyright {year}" --custom-file-header-mode prepend --disable-timestamp --enable-version-header # (1)!
    ```

    1. :material-arrow-left: `--custom-file-header-mode` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema",
      "type": "object",
      "properties": {"s": {"type": ["string"]}},
      "required": ["s"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # Copyright {year}
    #
    # generated by datamodel-codegen:
    #   filename:  simple_string.json
    #   version:   0.0.0

    from __future__ import annotations

    from pydantic import BaseModel


    class Model(BaseModel):
        s: str
    ```

    <!-- fmt: on -->

---

## `--custom-file-header-path` {#custom-file-header-path}

Add custom header content from file to generated code.

The `--custom-file-header-path` flag allows you to specify a file containing
custom header content (like copyright notices, linting directives, or module docstrings)
to be inserted at the top of generated Python files.

**Option relationships:**

- **Conflicts:** [`--custom-file-header`](template-customization.md#custom-file-header) - `--custom-file-header-path` can not be used with `--custom-file-header`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --custom-file-header-path custom_file_header.txt # (1)!
    ```

    1. :material-arrow-left: `--custom-file-header-path` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # multiline custom ;
    # header ;
    # file ;

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--custom-formatters` {#custom-formatters}

Apply custom Python code formatters to generated output.

The `--custom-formatters` flag allows you to specify custom Python functions
that will be applied to format the generated code. The formatter is specified
as a module path (e.g., "mymodule.formatter_function"). This is useful for
adding custom comments, modifying code structure, or applying project-specific
formatting rules beyond what black/isort provide.

**See also:** [Custom Code Formatters](../custom-formatters.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input custom-scalar-types.graphql --custom-formatters tests.data.python.custom_formatters.add_comment # (1)!
    ```

    1. :material-arrow-left: `--custom-formatters` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    scalar Long

    type A {
      id: ID!
      duration: Long!
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  custom-scalar-types.graphql
    #   timestamp: 2019-07-26T00:00:00+00:00

    # a comment
    from __future__ import annotations

    from typing import Literal

    from pydantic import BaseModel, Field
    from typing_extensions import TypeAliasType

    Boolean = TypeAliasType("Boolean", bool)
    """
    The `Boolean` scalar type represents `true` or `false`.
    """


    ID = TypeAliasType("ID", str)
    """
    The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
    """


    Long = TypeAliasType("Long", str)


    String = TypeAliasType("String", str)
    """
    The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
    """


    class A(BaseModel):
        duration: Long
        id: ID
        typename__: Literal['A'] | None = Field('A', alias='__typename')
    ```

    <!-- fmt: on -->

---

## `--custom-formatters-kwargs` {#custom-formatters-kwargs}

Pass custom arguments to custom formatters via inline JSON or a JSON file path.

The `--custom-formatters-kwargs` flag accepts an inline JSON object or a path to a JSON file containing
custom configuration for custom formatters (used with --custom-formatters).
The file should contain a JSON object mapping formatter names to their kwargs.

Note: This option is primarily used with --custom-formatters to pass
configuration to user-defined formatter modules.

**See also:** [Custom Code Formatters](../custom-formatters.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pet_simple.json --custom-formatters-kwargs formatter_kwargs.json # (1)!
    ```

    1. :material-arrow-left: `--custom-formatters-kwargs` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  pet_simple.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--custom-template-dir` {#custom-template-dir}

Use custom Jinja2 templates for model generation.

The `--custom-template-dir` option allows you to specify a directory containing custom Jinja2 templates
to override the default templates used for generating data models. This enables full customization of
the generated code structure and formatting. Use with `--extra-template-data` to pass additional data
to the templates.

**See also:** [Custom Templates](../custom_template.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --custom-template-dir templates --extra-template-data openapi/extra_data.json # (1)!
    ```

    1. :material-arrow-left: `--custom-template-dir` - the option documented here

<!-- BEGIN AUTO-GENERATED DOC EXAMPLE: cli-reference.template-customization.custom-template-dir.example -->
??? example "Examples"

    **Input Schema (`api.yaml`):**
    <!-- fmt: off -->

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    <!-- fmt: on -->

    **Template (`templates/pydantic/BaseModel.jinja2`):**
    <!-- fmt: off -->

    ```jinja2
    {% for decorator in decorators -%}
    {{ decorator }}
    {% endfor -%}
    class {{ class_name }}({{ base_class }}):{% if comment is defined %}  # {{ comment }}{% endif %}
    {%- if not fields %}
        pass
    {%- endif %}
    {%- for field in fields -%}
        {%- if field.required %}
        {{ field.name }}: {{ field.type_hint }}
        {%- else %}
        {{ field.name }}: {{ field.type_hint }} = {{ field.default }}
        {%- endif %}
        {%- if field.docstring %}
        """
        {{ field.docstring }}
        """
        {%- endif %}
    {%- endfor -%}
    ```

    <!-- fmt: on -->

    **Extra Template Data (`openapi/extra_data.json`):**
    <!-- fmt: off -->

    ```json
    {
      "Pet": {
        "comment": "1 2, 1 2, this is just a pet",
        "config":{
          "arbitrary_types_allowed": "True",
          "coerce_numbers_to_str": "True"}
      }
    }
    ```

    <!-- fmt: on -->

    **Output:**
    <!-- fmt: off -->

    ```python
    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel


    class Pet(BaseModel):  # 1 2, 1 2, this is just a pet
        model_config = ConfigDict(
            arbitrary_types_allowed=True,
            coerce_numbers_to_str=True,
        )
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->
<!-- END AUTO-GENERATED DOC EXAMPLE: cli-reference.template-customization.custom-template-dir.example -->

---

## `--disable-appending-item-suffix` {#disable-appending-item-suffix}

Disable appending 'Item' suffix to array item types.

The `--disable-appending-item-suffix` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api_constrained.yaml --disable-appending-item-suffix --field-constraints # (1)!
    ```

    1. :material-arrow-left: `--disable-appending-item-suffix` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
                minimum: 0
                maximum: 100
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              minimum: 0
              maximum: 9223372036854775807
            name:
              type: string
              maxLength: 256
            tag:
              type: string
              maxLength: 64
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
          maxItems: 10
          minItems: 1
          uniqueItems: true
        UID:
          type: integer
          minimum: 0
        Users:
          type: array
          items:
            required:
              - id
              - name
              - uid
            properties:
              id:
                type: integer
                format: int64
                minimum: 0
              name:
                type: string
                maxLength: 256
              tag:
                type: string
                maxLength: 64
              uid:
                $ref: '#/components/schemas/UID'
              phones:
                type: array
                items:
                  type: string
                  minLength: 3
                maxItems: 10
              fax:
                type: array
                items:
                  type: string
                  minLength: 3
              height:
                type:
                  - integer
                  - number
                minimum: 1
                maximum: 300
              weight:
                type:
                  - number
                  - integer
                minimum: 1.0
                maximum: 1000.0
              age:
                type: integer
                minimum: 0.0
                maximum: 200.0
                exclusiveMinimum: true
              rating:
                type: number
                minimum: 0
                exclusiveMinimum: true
                maximum: 5

        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                minLength: 1
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api_constrained.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int = Field(..., ge=0, le=9223372036854775807)
        name: str = Field(..., max_length=256)
        tag: str | None = Field(None, max_length=64)


    class Pets(RootModel[list[Pet]]):
        root: list[Pet] = Field(..., max_length=10, min_length=1)


    class UID(RootModel[int]):
        root: int = Field(..., ge=0)


    class Phone(RootModel[str]):
        root: str = Field(..., min_length=3)


    class Fax(RootModel[str]):
        root: str = Field(..., min_length=3)


    class User(BaseModel):
        id: int = Field(..., ge=0)
        name: str = Field(..., max_length=256)
        tag: str | None = Field(None, max_length=64)
        uid: UID
        phones: list[Phone] | None = Field(None, max_length=10)
        fax: list[Fax] | None = None
        height: int | float | None = Field(None, ge=1.0, le=300.0)
        weight: float | int | None = Field(None, ge=1.0, le=1000.0)
        age: int | None = Field(None, gt=0, le=200)
        rating: float | None = Field(None, gt=0.0, le=5.0)


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--disable-timestamp` {#disable-timestamp}

Disable timestamp in generated file header for reproducible output.

The `--disable-timestamp` flag configures the code generation behavior.

**See also:** [CI/CD Integration](../ci-cd.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pattern.json --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--disable-timestamp` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Info",
      "type": "object",
      "properties": {
        "hostName": {
          "type": "string",
          "format": "hostname"
        },
        "arn": {
          "type": "string",
          "pattern": "(^arn:([^:]*):([^:]*):([^:]*):(|\\*|[\\d]{12}):(.+)$)|^\\*$"
        },
        "tel": {
          "type": "string",
          "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
        },
        "comment": {
            "type": "string",
            "pattern": "[^\\x08\\f\\n\\r\\t\\\\a+.?'\"|()]+$"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  pattern.json

    from __future__ import annotations

    from pydantic import BaseModel, constr


    class Info(BaseModel):
        hostName: (
            constr(
                pattern=r'^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]{0,61}[A-Za-z0-9])$'
            )
            | None
        ) = None
        arn: (
            constr(pattern=r'(^arn:([^:]*):([^:]*):([^:]*):(|\*|[\d]{12}):(.+)$)|^\*$')
            | None
        ) = None
        tel: constr(pattern=r'^(\([0-9]{3}\))?[0-9]{3}-[0-9]{4}$') | None = None
        comment: constr(pattern=r'[^\x08\f\n\r\t\\a+.?\'"|()]+$') | None = None
    ```

    <!-- fmt: on -->

---

## `--enable-command-header` {#enable-command-header}

Include command-line options in file header for reproducibility.

The `--enable-command-header` flag adds the full command-line used to generate
the file to the header, making it easy to reproduce the generation. `--http-headers` and `--http-query-parameters`
values are shown as `<redacted>`, and `--url` like the `filename` line without its userinfo, query or fragment.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --enable-command-header # (1)!
    ```

    1. :material-arrow-left: `--enable-command-header` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00
    #   command:   datamodel-codegen [COMMAND]

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--enable-generated-header-marker` {#enable-generated-header-marker}

Include the @generated marker in file header for generated-code tooling.

The `--enable-generated-header-marker` flag marks generated output for tools that
recognize the `@generated` marker.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --enable-generated-header-marker # (1)!
    ```

    1. :material-arrow-left: `--enable-generated-header-marker` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # @generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--enable-version-header` {#enable-version-header}

Include tool version information in file header.

The `--enable-version-header` flag configures the code generation behavior.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --enable-version-header # (1)!
    ```

    1. :material-arrow-left: `--enable-version-header` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00
    #   version:   0.0.0

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--extra-template-data` {#extra-template-data}

Pass custom template variables via inline JSON or a JSON file path.

The `--extra-template-data` flag allows you to provide additional variables
from an inline JSON object or JSON file that can be used in custom templates to configure generated
model settings like Config classes, enabling customization beyond standard options.

**See also:** [Custom Templates](../custom_template.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --extra-template-data openapi/extra_data.json # (1)!
    ```

    1. :material-arrow-left: `--extra-template-data` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    === "Pydantic v2"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  api.yaml
        #   timestamp: 1985-10-26T08:21:00+00:00

        from __future__ import annotations

        from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel


        class Pet(BaseModel):  # 1 2, 1 2, this is just a pet
            model_config = ConfigDict(
                arbitrary_types_allowed=True,
                coerce_numbers_to_str=True,
            )
            id: int
            name: str
            tag: str | None = None


        class Pets(RootModel[list[Pet]]):
            root: list[Pet]


        class User(BaseModel):
            id: int
            name: str
            tag: str | None = None


        class Users(RootModel[list[User]]):
            root: list[User]


        class Id(RootModel[str]):
            root: str


        class Rules(RootModel[list[str]]):
            root: list[str]


        class Error(BaseModel):
            code: int
            message: str


        class Api(BaseModel):
            apiKey: str | None = Field(
                None, description='To be used as a dataset parameter value'
            )
            apiVersionNumber: str | None = Field(
                None, description='To be used as a version parameter value'
            )
            apiUrl: AnyUrl | None = Field(
                None, description="The URL describing the dataset's fields"
            )
            apiDocumentationUrl: AnyUrl | None = Field(
                None, description='A URL to the API console for each API'
            )


        class Apis(RootModel[list[Api]]):
            root: list[Api]


        class Event(BaseModel):
            name: str | None = None


        class Result(BaseModel):
            event: Event | None = None
        ```

        <!-- fmt: on -->

---

## `--formatters` {#formatters}

Specify code formatters to apply to generated output.

The `--formatters` flag specifies which code formatters to apply to
the generated Python code. Available formatters are: builtin, black,
isort, ruff-check, ruff-format. The current default is [black, isort].
For projects using Ruff, select --formatters ruff-check ruff-format to match project lint and formatting settings.
Use --formatters builtin when you use no external formatter or prioritize generation speed.
Keep --formatters black isort to preserve existing formatting. Explicit formatters override presets.
The future builtin default reduces installation dependencies and version constraints; Black/isort remain required today.
See the formatter guides for installation and custom-template limitations.

**See also:** [CI/CD Integration](../ci-cd.md), [Formatter behavior](../formatter-behavior.md), [Code Formatting](../formatting.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pet_simple.json --formatters isort # (1)!
    ```

    1. :material-arrow-left: `--formatters` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  pet_simple.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--generate-schema-validators` {#generate-schema-validators}

Generate experimental Pydantic v2 model validators for JSON Schema runtime rules.

The `--generate-schema-validators` option emits schema-derived model validators
for object constraints that cannot be represented as type hints alone, including
minProperties/maxProperties on named object models, patternProperties on
composed object models, required-only oneOf/anyOf groups, simple
if/then/else required-property conditions, and uniqueItems array validation.
This feature is experimental and may change as JSON Schema coverage is expanded.

With standard models and templates, required names absent from generated fields
are checked against the raw object input. This also preserves required names
that are not declared in `properties` when validating overlapping open object
patterns. `--force-optional` retains its existing behavior. Custom base classes,
custom templates, and extra template data retain their previous handling of
undeclared required names.

When generating uniqueItems validation, do not override
`pydantic_v2/schema_runtime_validation_helpers.jinja2`; custom helper overrides
are unsupported and generation fails fast.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema_validators.json --generate-schema-validators --output-model-type pydantic_v2.BaseModel --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--generate-schema-validators` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$defs": {
        "First": {
          "type": "object",
          "properties": {
            "first": {
              "type": "string"
            }
          },
          "required": ["first"]
        },
        "Second": {
          "type": "object",
          "properties": {
            "second": {
              "type": "string"
            }
          },
          "required": ["second"]
        },
        "PatternBag": {
          "type": "object",
          "patternProperties": {
            "^[A-Z][A-Za-z0-9_]*$": {
              "$ref": "#/$defs/Second"
            }
          },
          "additionalProperties": false
        },
        "PatternTarget": {
          "allOf": [
            {
              "$ref": "#/$defs/First"
            },
            {
              "$ref": "#/$defs/PatternBag"
            }
          ]
        },
        "DirectPatternBag": {
          "type": "object",
          "patternProperties": {
            "^item_[0-9]+$": {
              "type": "integer"
            }
          },
          "additionalProperties": false
        },
        "ValidatorOnlyChild": {
          "allOf": [
            {
              "$ref": "#/$defs/First"
            },
            {
              "type": "object",
              "patternProperties": {
                "^extra_[A-Za-z]+$": {
                  "type": "integer"
                }
              },
              "additionalProperties": false
            }
          ]
        },
        "ValidatorOnlyPatternRef": {
          "allOf": [
            {
              "$ref": "#/$defs/First"
            }
          ],
          "patternProperties": {
            "^ref_extra_[A-Za-z]+$": {
              "type": "integer"
            }
          },
          "additionalProperties": false
        },
        "OneOfContact": {
          "type": "object",
          "properties": {
            "email": {
              "type": "string"
            },
            "phone": {
              "type": "string"
            }
          },
          "oneOf": [
            {
              "required": ["email"]
            },
            {
              "required": ["phone"]
            }
          ]
        },
        "AnyOfContact": {
          "type": "object",
          "properties": {
            "email": {
              "type": "string"
            },
            "phone": {
              "type": "string"
            }
          },
          "anyOf": [
            {
              "required": ["email"]
            },
            {
              "required": ["phone"]
            }
          ]
        },
        "ConditionalPayload": {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string"
            }
          },
          "if": {
            "properties": {
              "kind": {
                "const": "metric"
              }
            },
            "required": ["kind"]
          },
          "then": {
            "properties": {
              "metric": {
                "type": "integer"
              }
            },
            "required": ["metric"]
          },
          "else": {
            "properties": {
              "note": {
                "type": "string"
              }
            },
            "required": ["note"]
          }
        },
        "RequiredOnlyGuard": {
          "type": "object",
          "properties": {
            "flag": {
              "type": "string"
            }
          },
          "oneOf": [
            {},
            {
              "required": []
            }
          ]
        }
      },
      "$ref": "#/$defs/PatternTarget"
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  schema_validators.json

    from __future__ import annotations

    import re
    from collections.abc import Mapping as _Mapping
    from typing import Any, ClassVar

    from pydantic import BaseModel, ConfigDict, RootModel, TypeAdapter, model_validator


    class _JsonSchemaRuntimeValidationBase(BaseModel):
        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = ()
        __json_schema_one_of_required_groups__: ClassVar[tuple[Any, ...]] = ()
        __json_schema_any_of_required_groups__: ClassVar[tuple[Any, ...]] = ()
        __json_schema_conditional_required__: ClassVar[tuple[Any, ...]] = ()

        @model_validator(mode='before')
        @classmethod
        def _validate_json_schema_runtime_rules(cls, data: Any) -> Any:
            data = cls._validate_json_schema_pattern_properties(data)
            data = cls._validate_json_schema_required_groups(
                data,
                required_group_rules=cls.__json_schema_one_of_required_groups__,
                require_exactly_one=True,
            )
            data = cls._validate_json_schema_required_groups(
                data,
                required_group_rules=cls.__json_schema_any_of_required_groups__,
                require_exactly_one=False,
            )
            data = cls._validate_json_schema_conditional_required(data)
            return data

        @classmethod
        def _validate_json_schema_pattern_properties(cls, data: Any) -> Any:
            if not (isinstance(data, dict) or isinstance(data, _Mapping)):
                return data
            values = data
            for rule in cls.__json_schema_pattern_properties__:
                pattern_adapters = None
                additional_adapter = None
                for key, value in data.items():
                    if key in rule['declared_properties']:
                        continue
                    if any(
                        re.search(pattern, key) for pattern in rule['rejected_patterns']
                    ):
                        raise ValueError(
                            f'Property {key!r} is not allowed by patternProperties'
                        )
                    matched = False
                    for index, (pattern, value_type) in enumerate(
                        rule['pattern_properties'],
                    ):
                        if not re.search(pattern, key):
                            continue
                        matched = True
                        if pattern_adapters is None:
                            pattern_adapters = {}
                        if (adapter := pattern_adapters.get(index)) is None:
                            adapter = TypeAdapter(value_type)
                            pattern_adapters[index] = adapter
                        value = adapter.validate_python(value)
                    if matched:
                        if values is data:
                            values = dict(data)
                        values[key] = value
                        continue
                    if rule['additional_property_type'] is not None:
                        if additional_adapter is None:
                            additional_adapter = TypeAdapter(
                                rule['additional_property_type'],
                            )
                        if values is data:
                            values = dict(data)
                        values[key] = additional_adapter.validate_python(value)
                        continue
                    if not rule['allow_unmatched']:
                        raise ValueError(f'Unexpected property {key!r}')
            return values

        @classmethod
        def _validate_json_schema_required_groups(
            cls,
            data: Any,
            *,
            required_group_rules: tuple[Any, ...],
            require_exactly_one: bool,
        ) -> Any:
            if not required_group_rules:
                return data
            if not (isinstance(data, dict) or isinstance(data, _Mapping)):
                return data
            for required_groups in required_group_rules:
                matches = sum(
                    all(any(name in data for name in names) for names in group)
                    for group in required_groups
                )
                if require_exactly_one:
                    if matches != 1:
                        raise ValueError(
                            'Expected exactly one required property group to be present'
                        )
                elif matches == 0:
                    raise ValueError(
                        'Expected at least one required property group to be present'
                    )
            return data

        @classmethod
        def _validate_json_schema_conditional_required(cls, data: Any) -> Any:
            if not (isinstance(data, dict) or isinstance(data, _Mapping)):
                return data
            for rule in cls.__json_schema_conditional_required__:
                condition_matches = all(
                    any(name in data and data[name] in expected for name in names)
                    for names, expected in rule['condition']
                )
                required_groups = (
                    rule['then_required_groups']
                    if condition_matches
                    else rule['else_required_groups']
                )
                for group in required_groups:
                    if all(any(name in data for name in names) for names in group):
                        continue
                    raise ValueError('Conditional required properties are missing')
            return data


    class First(BaseModel):
        first: str


    class Second(BaseModel):
        second: str


    class PatternBag(_JsonSchemaRuntimeValidationBase):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': (),
                'rejected_patterns': (),
                'pattern_properties': (('^[A-Z][A-Za-z0-9_]*$', Second),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class PatternTarget(First, PatternBag):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': ('first',),
                'rejected_patterns': (),
                'pattern_properties': (('^[A-Z][A-Za-z0-9_]*$', Second),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class DirectPatternBag(_JsonSchemaRuntimeValidationBase):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': (),
                'rejected_patterns': (),
                'pattern_properties': (('^item_[0-9]+$', int),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class ValidatorOnlyChild(_JsonSchemaRuntimeValidationBase, First):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': ('first',),
                'rejected_patterns': (),
                'pattern_properties': (('^extra_[A-Za-z]+$', int),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class ValidatorOnlyPatternRef(_JsonSchemaRuntimeValidationBase, First):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': ('first',),
                'rejected_patterns': (),
                'pattern_properties': (('^ref_extra_[A-Za-z]+$', int),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class OneOfContact(_JsonSchemaRuntimeValidationBase):
        __json_schema_one_of_required_groups__: ClassVar[tuple[Any, ...]] = (
            ((('email',),), (('phone',),)),
        )

        email: str | None = None
        phone: str | None = None


    class AnyOfContact(_JsonSchemaRuntimeValidationBase):
        __json_schema_any_of_required_groups__: ClassVar[tuple[Any, ...]] = (
            ((('email',),), (('phone',),)),
        )

        email: str | None = None
        phone: str | None = None


    class ConditionalPayload(_JsonSchemaRuntimeValidationBase):
        __json_schema_conditional_required__: ClassVar[tuple[Any, ...]] = (
            {
                'condition': ((('kind',), ('metric',)),),
                'then_required_groups': ((('metric',),),),
                'else_required_groups': ((('note',),),),
            },
        )

        kind: str | None = None
        metric: int | None = None
        note: str | None = None


    class RequiredOnlyGuard1(BaseModel):
        flag: str | None = None


    class RequiredOnlyGuard(RootModel[RequiredOnlyGuard1]):
        root: RequiredOnlyGuard1


    class Model(RootModel[PatternTarget]):
        root: PatternTarget
    ```

    <!-- fmt: on -->

---

## `--no-treat-dot-as-module` {#no-treat-dot-as-module}

Keep dots in schema names as underscores for flat output.

The `--no-treat-dot-as-module` flag prevents splitting dotted schema names.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input treat_dot_as_module_single --no-treat-dot-as-module # (1)!
    ```

    1. :material-arrow-left: `--no-treat-dot-as-module` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    # model.schema.json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "User",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        }
      },
      "required": ["name"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # __init__.py
    # generated by datamodel-codegen:
    #   filename:  treat_dot_as_module_single
    #   timestamp: 2019-07-26T00:00:00+00:00

    # model_schema.py
    # generated by datamodel-codegen:
    #   filename:  model.schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class User(BaseModel):
        name: str
        age: int | None = None
    ```

    <!-- fmt: on -->

---

## `--no-use-type-checking-imports` {#no-use-type-checking-imports}

Keep generated model imports available at runtime when using Ruff fixes.

The `--no-use-type-checking-imports` flag prevents Ruff from moving generated model imports
into `TYPE_CHECKING` blocks. This is useful for modular Pydantic output where referenced
models need to be importable at runtime without calling `model_rebuild()` manually.
In the multi-module Pydantic + `ruff-check` case, runtime imports are preserved by default.
`--use-type-checking-imports` opts back into the old TYPE_CHECKING-only behavior, which can
require manual `model_rebuild()` calls for cross-module runtime references.

**Related:** [`--formatters`](#formatters), [`--use-exact-imports`](#use-exact-imports), [`--use-type-checking-imports`](#use-type-checking-imports)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input modular.yaml --output-model-type pydantic_v2.BaseModel --formatters ruff-check ruff-format --no-use-type-checking-imports --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--no-use-type-checking-imports` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Modular Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/collections.Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/collections.Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        models.Species:
          type: string
          enum:
            - dog
            - cat
            - snake
        models.Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
            species:
              $ref: '#/components/schemas/models.Species'
        models.User:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
        collections.Pets:
          type: array
          items:
            $ref: "#/components/schemas/models.Pet"
        collections.Users:
          type: array
          items:
            $ref: "#/components/schemas/models.User"
        optional:
          type: string
        Id:
          type: string
        collections.Rules:
          type: array
          items:
            type: string
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        collections.apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
              stage:
                type: string
                enum: [
                  "test",
                  "dev",
                  "stg",
                  "prod"
                ]
        models.Event:
          type: object
          properties:
            name:
              anyOf:
                - type: string
                - type: number
                - type: integer
                - type: boolean
                - type: object
                - type: array
                  items:
                    type: string
        Result:
          type: object
          properties:
            event:
              $ref: '#/components/schemas/models.Event'
        foo.bar.Thing:
          properties:
            attributes:
              type: object
        foo.bar.Thang:
          properties:
            attributes:
              type: array
              items:
                type: object
        foo.bar.Clone:
          allOf:
            - $ref: '#/components/schemas/foo.bar.Thing'
            - type: object
              properties:
                others:
                  type: object
                  properties:
                     name:
                       type: string

        foo.Tea:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
        Source:
          properties:
            country:
              type: string
        foo.Cocoa:
          properties:
            quality:
              type: integer
        bar.Field:
          type: string
          example: green
        woo.boo.Chocolate:
          properties:
            flavour:
              type: string
            source:
              $ref: '#/components/schemas/Source'
            cocoa:
              $ref: '#/components/schemas/foo.Cocoa'
            field:
              $ref: '#/components/schemas/bar.Field'
        differentTea:
          type: object
          properties:
            foo:
              $ref: '#/components/schemas/foo.Tea'
            nested:
              $ref: '#/components/schemas/nested.foo.Tea'
        nested.foo.Tea:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
            self:
              $ref: '#/components/schemas/nested.foo.Tea'
            optional:
              type: array
              items:
                $ref: '#/components/schemas/optional'
        nested.foo.TeaClone:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
            self:
              $ref: '#/components/schemas/nested.foo.Tea'
            optional:
              type: array
              items:
                $ref: '#/components/schemas/optional'
        nested.foo.List:
          type: array
          items:
            $ref: '#/components/schemas/nested.foo.Tea'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  _internal

    from __future__ import annotations

    from pydantic import BaseModel, RootModel

    from . import models


    class Optional(RootModel[str]):
        root: str


    class Id(RootModel[str]):
        root: str


    class Error(BaseModel):
        code: int
        message: str


    class Result(BaseModel):
        event: models.Event | None = None


    class Source(BaseModel):
        country: str | None = None


    class DifferentTea(BaseModel):
        foo: Tea | None = None
        nested: Tea_1 | None = None


    class Tea(BaseModel):
        flavour: str | None = None
        id: Id | None = None


    class Cocoa(BaseModel):
        quality: int | None = None


    class Tea_1(BaseModel):
        flavour: str | None = None
        id: Id | None = None
        self: Tea_1 | None = None
        optional: list[Optional] | None = None


    class TeaClone(BaseModel):
        flavour: str | None = None
        id: Id | None = None
        self: Tea_1 | None = None
        optional: list[Optional] | None = None


    class List(RootModel[list[Tea_1]]):
        root: list[Tea_1]


    Tea_1.model_rebuild()
    ```

    <!-- fmt: on -->

---

## `--schema-validator-base-class-name` {#schema-validator-base-class-name}

Set the generated shared Pydantic v2 schema runtime validator base class name.

The `--schema-validator-base-class-name` option changes the name of the generated
shared base class that owns schema-derived runtime validators. It is only used when
`--generate-schema-validators` emits shared validator code.

**Related:** [`--generate-schema-validators`](#generate-schema-validators)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema_validators_custom_base_class_name.json --generate-schema-validators --schema-validator-base-class-name SharedSchemaValidatorBase --output-model-type pydantic_v2.BaseModel --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--schema-validator-base-class-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "title": "CustomBaseClassName",
      "type": "object",
      "patternProperties": {
        "^item_[0-9]+$": {
          "type": "integer"
        }
      },
      "additionalProperties": false
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  schema_validators_custom_base_class_name.json

    from __future__ import annotations

    import re
    from collections.abc import Mapping as _Mapping
    from typing import Any, ClassVar

    from pydantic import BaseModel, ConfigDict, TypeAdapter, model_validator


    class SharedSchemaValidatorBase(BaseModel):
        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = ()

        @model_validator(mode='before')
        @classmethod
        def _validate_json_schema_runtime_rules(cls, data: Any) -> Any:
            data = cls._validate_json_schema_pattern_properties(data)
            return data

        @classmethod
        def _validate_json_schema_pattern_properties(cls, data: Any) -> Any:
            if not (isinstance(data, dict) or isinstance(data, _Mapping)):
                return data
            values = data
            for rule in cls.__json_schema_pattern_properties__:
                pattern_adapters = None
                additional_adapter = None
                for key, value in data.items():
                    if key in rule['declared_properties']:
                        continue
                    if any(
                        re.search(pattern, key) for pattern in rule['rejected_patterns']
                    ):
                        raise ValueError(
                            f'Property {key!r} is not allowed by patternProperties'
                        )
                    matched = False
                    for index, (pattern, value_type) in enumerate(
                        rule['pattern_properties'],
                    ):
                        if not re.search(pattern, key):
                            continue
                        matched = True
                        if pattern_adapters is None:
                            pattern_adapters = {}
                        if (adapter := pattern_adapters.get(index)) is None:
                            adapter = TypeAdapter(value_type)
                            pattern_adapters[index] = adapter
                        value = adapter.validate_python(value)
                    if matched:
                        if values is data:
                            values = dict(data)
                        values[key] = value
                        continue
                    if rule['additional_property_type'] is not None:
                        if additional_adapter is None:
                            additional_adapter = TypeAdapter(
                                rule['additional_property_type'],
                            )
                        if values is data:
                            values = dict(data)
                        values[key] = additional_adapter.validate_python(value)
                        continue
                    if not rule['allow_unmatched']:
                        raise ValueError(f'Unexpected property {key!r}')
            return values


    class CustomBaseClassName(SharedSchemaValidatorBase):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': (),
                'rejected_patterns': (),
                'pattern_properties': (('^item_[0-9]+$', int),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )
    ```

    <!-- fmt: on -->

---

## `--schema-validator-type` {#schema-validator-type}

Select the schema-derived runtime validator backend.

The `--schema-validator-type pydantic-v2` option enables the current generated
Pydantic v2 model-validator backend for JSON Schema rules that cannot be
represented as type hints alone. The explicit type keeps the CLI ready for
additional validator backends without adding them in this release.

**Related:** [`--generate-schema-validators`](#generate-schema-validators)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema_validators.json --schema-validator-type pydantic-v2 --output-model-type pydantic_v2.BaseModel --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--schema-validator-type` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$defs": {
        "First": {
          "type": "object",
          "properties": {
            "first": {
              "type": "string"
            }
          },
          "required": ["first"]
        },
        "Second": {
          "type": "object",
          "properties": {
            "second": {
              "type": "string"
            }
          },
          "required": ["second"]
        },
        "PatternBag": {
          "type": "object",
          "patternProperties": {
            "^[A-Z][A-Za-z0-9_]*$": {
              "$ref": "#/$defs/Second"
            }
          },
          "additionalProperties": false
        },
        "PatternTarget": {
          "allOf": [
            {
              "$ref": "#/$defs/First"
            },
            {
              "$ref": "#/$defs/PatternBag"
            }
          ]
        },
        "DirectPatternBag": {
          "type": "object",
          "patternProperties": {
            "^item_[0-9]+$": {
              "type": "integer"
            }
          },
          "additionalProperties": false
        },
        "ValidatorOnlyChild": {
          "allOf": [
            {
              "$ref": "#/$defs/First"
            },
            {
              "type": "object",
              "patternProperties": {
                "^extra_[A-Za-z]+$": {
                  "type": "integer"
                }
              },
              "additionalProperties": false
            }
          ]
        },
        "ValidatorOnlyPatternRef": {
          "allOf": [
            {
              "$ref": "#/$defs/First"
            }
          ],
          "patternProperties": {
            "^ref_extra_[A-Za-z]+$": {
              "type": "integer"
            }
          },
          "additionalProperties": false
        },
        "OneOfContact": {
          "type": "object",
          "properties": {
            "email": {
              "type": "string"
            },
            "phone": {
              "type": "string"
            }
          },
          "oneOf": [
            {
              "required": ["email"]
            },
            {
              "required": ["phone"]
            }
          ]
        },
        "AnyOfContact": {
          "type": "object",
          "properties": {
            "email": {
              "type": "string"
            },
            "phone": {
              "type": "string"
            }
          },
          "anyOf": [
            {
              "required": ["email"]
            },
            {
              "required": ["phone"]
            }
          ]
        },
        "ConditionalPayload": {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string"
            }
          },
          "if": {
            "properties": {
              "kind": {
                "const": "metric"
              }
            },
            "required": ["kind"]
          },
          "then": {
            "properties": {
              "metric": {
                "type": "integer"
              }
            },
            "required": ["metric"]
          },
          "else": {
            "properties": {
              "note": {
                "type": "string"
              }
            },
            "required": ["note"]
          }
        },
        "RequiredOnlyGuard": {
          "type": "object",
          "properties": {
            "flag": {
              "type": "string"
            }
          },
          "oneOf": [
            {},
            {
              "required": []
            }
          ]
        }
      },
      "$ref": "#/$defs/PatternTarget"
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  schema_validators.json

    from __future__ import annotations

    import re
    from collections.abc import Mapping as _Mapping
    from typing import Any, ClassVar

    from pydantic import BaseModel, ConfigDict, RootModel, TypeAdapter, model_validator


    class _JsonSchemaRuntimeValidationBase(BaseModel):
        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = ()
        __json_schema_one_of_required_groups__: ClassVar[tuple[Any, ...]] = ()
        __json_schema_any_of_required_groups__: ClassVar[tuple[Any, ...]] = ()
        __json_schema_conditional_required__: ClassVar[tuple[Any, ...]] = ()

        @model_validator(mode='before')
        @classmethod
        def _validate_json_schema_runtime_rules(cls, data: Any) -> Any:
            data = cls._validate_json_schema_pattern_properties(data)
            data = cls._validate_json_schema_required_groups(
                data,
                required_group_rules=cls.__json_schema_one_of_required_groups__,
                require_exactly_one=True,
            )
            data = cls._validate_json_schema_required_groups(
                data,
                required_group_rules=cls.__json_schema_any_of_required_groups__,
                require_exactly_one=False,
            )
            data = cls._validate_json_schema_conditional_required(data)
            return data

        @classmethod
        def _validate_json_schema_pattern_properties(cls, data: Any) -> Any:
            if not (isinstance(data, dict) or isinstance(data, _Mapping)):
                return data
            values = data
            for rule in cls.__json_schema_pattern_properties__:
                pattern_adapters = None
                additional_adapter = None
                for key, value in data.items():
                    if key in rule['declared_properties']:
                        continue
                    if any(
                        re.search(pattern, key) for pattern in rule['rejected_patterns']
                    ):
                        raise ValueError(
                            f'Property {key!r} is not allowed by patternProperties'
                        )
                    matched = False
                    for index, (pattern, value_type) in enumerate(
                        rule['pattern_properties'],
                    ):
                        if not re.search(pattern, key):
                            continue
                        matched = True
                        if pattern_adapters is None:
                            pattern_adapters = {}
                        if (adapter := pattern_adapters.get(index)) is None:
                            adapter = TypeAdapter(value_type)
                            pattern_adapters[index] = adapter
                        value = adapter.validate_python(value)
                    if matched:
                        if values is data:
                            values = dict(data)
                        values[key] = value
                        continue
                    if rule['additional_property_type'] is not None:
                        if additional_adapter is None:
                            additional_adapter = TypeAdapter(
                                rule['additional_property_type'],
                            )
                        if values is data:
                            values = dict(data)
                        values[key] = additional_adapter.validate_python(value)
                        continue
                    if not rule['allow_unmatched']:
                        raise ValueError(f'Unexpected property {key!r}')
            return values

        @classmethod
        def _validate_json_schema_required_groups(
            cls,
            data: Any,
            *,
            required_group_rules: tuple[Any, ...],
            require_exactly_one: bool,
        ) -> Any:
            if not required_group_rules:
                return data
            if not (isinstance(data, dict) or isinstance(data, _Mapping)):
                return data
            for required_groups in required_group_rules:
                matches = sum(
                    all(any(name in data for name in names) for names in group)
                    for group in required_groups
                )
                if require_exactly_one:
                    if matches != 1:
                        raise ValueError(
                            'Expected exactly one required property group to be present'
                        )
                elif matches == 0:
                    raise ValueError(
                        'Expected at least one required property group to be present'
                    )
            return data

        @classmethod
        def _validate_json_schema_conditional_required(cls, data: Any) -> Any:
            if not (isinstance(data, dict) or isinstance(data, _Mapping)):
                return data
            for rule in cls.__json_schema_conditional_required__:
                condition_matches = all(
                    any(name in data and data[name] in expected for name in names)
                    for names, expected in rule['condition']
                )
                required_groups = (
                    rule['then_required_groups']
                    if condition_matches
                    else rule['else_required_groups']
                )
                for group in required_groups:
                    if all(any(name in data for name in names) for names in group):
                        continue
                    raise ValueError('Conditional required properties are missing')
            return data


    class First(BaseModel):
        first: str


    class Second(BaseModel):
        second: str


    class PatternBag(_JsonSchemaRuntimeValidationBase):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': (),
                'rejected_patterns': (),
                'pattern_properties': (('^[A-Z][A-Za-z0-9_]*$', Second),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class PatternTarget(First, PatternBag):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': ('first',),
                'rejected_patterns': (),
                'pattern_properties': (('^[A-Z][A-Za-z0-9_]*$', Second),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class DirectPatternBag(_JsonSchemaRuntimeValidationBase):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': (),
                'rejected_patterns': (),
                'pattern_properties': (('^item_[0-9]+$', int),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class ValidatorOnlyChild(_JsonSchemaRuntimeValidationBase, First):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': ('first',),
                'rejected_patterns': (),
                'pattern_properties': (('^extra_[A-Za-z]+$', int),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class ValidatorOnlyPatternRef(_JsonSchemaRuntimeValidationBase, First):
        model_config = ConfigDict(
            extra='allow',
        )

        __json_schema_pattern_properties__: ClassVar[tuple[Any, ...]] = (
            {
                'declared_properties': ('first',),
                'rejected_patterns': (),
                'pattern_properties': (('^ref_extra_[A-Za-z]+$', int),),
                'additional_property_type': None,
                'allow_unmatched': False,
            },
        )


    class OneOfContact(_JsonSchemaRuntimeValidationBase):
        __json_schema_one_of_required_groups__: ClassVar[tuple[Any, ...]] = (
            ((('email',),), (('phone',),)),
        )

        email: str | None = None
        phone: str | None = None


    class AnyOfContact(_JsonSchemaRuntimeValidationBase):
        __json_schema_any_of_required_groups__: ClassVar[tuple[Any, ...]] = (
            ((('email',),), (('phone',),)),
        )

        email: str | None = None
        phone: str | None = None


    class ConditionalPayload(_JsonSchemaRuntimeValidationBase):
        __json_schema_conditional_required__: ClassVar[tuple[Any, ...]] = (
            {
                'condition': ((('kind',), ('metric',)),),
                'then_required_groups': ((('metric',),),),
                'else_required_groups': ((('note',),),),
            },
        )

        kind: str | None = None
        metric: int | None = None
        note: str | None = None


    class RequiredOnlyGuard1(BaseModel):
        flag: str | None = None


    class RequiredOnlyGuard(RootModel[RequiredOnlyGuard1]):
        root: RequiredOnlyGuard1


    class Model(RootModel[PatternTarget]):
        root: PatternTarget
    ```

    <!-- fmt: on -->

---

## `--strict-dotted-module-names` {#strict-dotted-module-names}

Require canonical Python identifiers when inferring dotted module paths.

The `--strict-dotted-module-names` flag applies only to automatic module inference.

**See also:** [Module Structure and Exports](../module-exports.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input invalid_dotted_schema_name.yaml --strict-dotted-module-names # (1)!
    ```

    1. :material-arrow-left: `--strict-dotted-module-names` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.0.0
    info:
      title: Invalid dotted schema name
      version: 1.0.0
    paths: {}
    components:
      schemas:
        Shipment:
          type: object
          properties:
            trackingNumber:
              type: string
        SaveTrifectaV2.1:
          type: object
          properties:
            shipment:
              type: object
              properties:
                trackingNumber:
                  type: string
        SaveRequest:
          type: object
          properties:
            shipment:
              $ref: '#/components/schemas/Shipment'
            trifecta:
              $ref: '#/components/schemas/SaveTrifectaV2.1'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  invalid_dotted_schema_name.yaml
    #   timestamp: 1985-10-26T08:21:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Shipment(BaseModel):
        trackingNumber: str | None = None


    class SaveTrifectaV21(BaseModel):
        shipment: Shipment | None = None


    class SaveRequest(BaseModel):
        shipment: Shipment | None = None
        trifecta: SaveTrifectaV21 | None = None
    ```

    <!-- fmt: on -->

---

## `--treat-dot-as-module` {#treat-dot-as-module}

Treat dots in schema names as module separators.

The `--treat-dot-as-module` flag configures the code generation behavior.

**See also:** [Module Structure and Exports](../module-exports.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input treat_dot_as_module_single --treat-dot-as-module # (1)!
    ```

    1. :material-arrow-left: `--treat-dot-as-module` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    # model.schema.json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "User",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        }
      },
      "required": ["name"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # __init__.py
    # generated by datamodel-codegen:
    #   filename:  treat_dot_as_module_single
    #   timestamp: 2019-07-26T00:00:00+00:00

    # model/__init__.py
    # generated by datamodel-codegen:
    #   filename:  treat_dot_as_module_single
    #   timestamp: 2019-07-26T00:00:00+00:00

    # model/schema.py
    # generated by datamodel-codegen:
    #   filename:  model.schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class User(BaseModel):
        name: str
        age: int | None = None
    ```

    <!-- fmt: on -->

---

## `--use-double-quotes` {#use-double-quotes}

Use double quotes for string literals in generated code.

The --use-double-quotes option formats all string literals in the generated
Python code with double quotes instead of the default single quotes. This
helps maintain consistency with codebases that prefer double-quote formatting.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input all_of_any_of_base_class_ref.json --use-double-quotes # (1)!
    ```

    1. :material-arrow-left: `--use-double-quotes` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$id": "https://example.com/schemas/MapState.json",
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "MapState",
      "allOf": [
        {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "latitude": {"type": "number", "minimum": -90, "maximum": 90},
                "longitude": {"type": "number", "minimum": -180, "maximum": 180},
                "zoom": {"type": "number", "minimum": 0, "maximum": 25, "default": 0},
                "bearing": {"type": "number"},
                "pitch": {"type": "number", "minimum": 0, "exclusiveMaximum": 90},
                "dragRotate": {"type": "boolean"},
                "mapSplitMode": {"type": "string", "const": "SINGLE_MAP"},
                "isSplit": {"type": "boolean", "const": false, "default": false}
              },
              "required": ["latitude", "longitude", "pitch", "mapSplitMode"]
            },
            {
              "type": "object",
              "properties": {
                "latitude": {"$ref": "#/allOf/0/anyOf/0/properties/latitude"},
                "longitude": {"$ref": "#/allOf/0/anyOf/0/properties/longitude"},
                "zoom": {"$ref": "#/allOf/0/anyOf/0/properties/zoom"},
                "bearing": {"$ref": "#/allOf/0/anyOf/0/properties/bearing"},
                "pitch": {"$ref": "#/allOf/0/anyOf/0/properties/pitch"},
                "dragRotate": {"$ref": "#/allOf/0/anyOf/0/properties/dragRotate"},
                "mapSplitMode": {"type": "string", "const": "SWIPE_COMPARE"},
                "isSplit": {"type": "boolean", "const": true, "default": true}
              },
              "required": ["latitude", "longitude", "pitch", "mapSplitMode"]
            }
          ]
        },
        {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "mapViewMode": {"type": "string", "const": "MODE_2D"}
              },
              "required": ["mapViewMode"]
            },
            {
              "type": "object",
              "properties": {
                "mapViewMode": {"type": "string", "const": "MODE_3D"}
              },
              "required": ["mapViewMode"]
            }
          ]
        }
      ]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  all_of_any_of_base_class_ref.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Literal

    from pydantic import BaseModel, Field, RootModel, confloat


    class MapState1(BaseModel):
        map_view_mode: Literal["MODE_2D"] = Field(..., alias="mapViewMode")


    class MapState2(BaseModel):
        latitude: Latitude
        longitude: Longitude
        zoom: Zoom | None = Field(0, validate_default=True)
        bearing: Bearing | None = None
        pitch: Pitch
        drag_rotate: DragRotate | None = Field(None, alias="dragRotate")
        map_split_mode: Literal["SWIPE_COMPARE"] = Field(..., alias="mapSplitMode")
        is_split: Literal[True] = Field(True, alias="isSplit")


    class MapState3(BaseModel):
        pass


    class MapState4(MapState1, MapState3):
        pass


    class MapState5(MapState2, MapState3):
        pass


    class MapState6(MapState4):
        pass


    class MapState7(MapState5):
        pass


    class MapState(RootModel[MapState4 | MapState5 | MapState6 | MapState7]):
        root: MapState4 | MapState5 | MapState6 | MapState7 = Field(..., title="MapState")


    class Bearing(RootModel[float]):
        root: float


    class DragRotate(RootModel[bool]):
        root: bool


    class Latitude(RootModel[confloat(ge=-90.0, le=90.0)]):
        root: confloat(ge=-90.0, le=90.0)


    class Longitude(RootModel[confloat(ge=-180.0, le=180.0)]):
        root: confloat(ge=-180.0, le=180.0)


    class Pitch(RootModel[confloat(ge=0.0, lt=90.0)]):
        root: confloat(ge=0.0, lt=90.0)


    class Zoom(RootModel[confloat(ge=0.0, le=25.0)]):
        root: confloat(ge=0.0, le=25.0) = 0
    ```

    <!-- fmt: on -->

---

## `--use-exact-imports` {#use-exact-imports}

Import exact types instead of modules.

The `--use-exact-imports` flag changes import style from module imports
to exact type imports. For example, instead of `from . import foo` then
`foo.Bar`, it generates `from .foo import Bar`. This can make the generated
code more explicit and easier to read.

Note: This option primarily affects modular output where imports between
modules are generated. For single-file output, the difference is minimal.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pet_simple.json --use-exact-imports # (1)!
    ```

    1. :material-arrow-left: `--use-exact-imports` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  pet_simple.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--use-type-checking-imports` {#use-type-checking-imports}

Allow Ruff to move typing-only imports into TYPE_CHECKING blocks.

The `--use-type-checking-imports` flag explicitly re-enables Ruff's TYPE_CHECKING import moves
for multi-module Pydantic output where runtime imports might otherwise be preserved by default.

**Related:** [`--formatters`](#formatters), [`--no-use-type-checking-imports`](#no-use-type-checking-imports), [`--use-exact-imports`](#use-exact-imports)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input modular.yaml --output-model-type pydantic_v2.BaseModel --formatters ruff-check ruff-format --use-type-checking-imports --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--use-type-checking-imports` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Modular Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/collections.Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/collections.Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        models.Species:
          type: string
          enum:
            - dog
            - cat
            - snake
        models.Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
            species:
              $ref: '#/components/schemas/models.Species'
        models.User:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
        collections.Pets:
          type: array
          items:
            $ref: "#/components/schemas/models.Pet"
        collections.Users:
          type: array
          items:
            $ref: "#/components/schemas/models.User"
        optional:
          type: string
        Id:
          type: string
        collections.Rules:
          type: array
          items:
            type: string
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        collections.apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
              stage:
                type: string
                enum: [
                  "test",
                  "dev",
                  "stg",
                  "prod"
                ]
        models.Event:
          type: object
          properties:
            name:
              anyOf:
                - type: string
                - type: number
                - type: integer
                - type: boolean
                - type: object
                - type: array
                  items:
                    type: string
        Result:
          type: object
          properties:
            event:
              $ref: '#/components/schemas/models.Event'
        foo.bar.Thing:
          properties:
            attributes:
              type: object
        foo.bar.Thang:
          properties:
            attributes:
              type: array
              items:
                type: object
        foo.bar.Clone:
          allOf:
            - $ref: '#/components/schemas/foo.bar.Thing'
            - type: object
              properties:
                others:
                  type: object
                  properties:
                     name:
                       type: string

        foo.Tea:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
        Source:
          properties:
            country:
              type: string
        foo.Cocoa:
          properties:
            quality:
              type: integer
        bar.Field:
          type: string
          example: green
        woo.boo.Chocolate:
          properties:
            flavour:
              type: string
            source:
              $ref: '#/components/schemas/Source'
            cocoa:
              $ref: '#/components/schemas/foo.Cocoa'
            field:
              $ref: '#/components/schemas/bar.Field'
        differentTea:
          type: object
          properties:
            foo:
              $ref: '#/components/schemas/foo.Tea'
            nested:
              $ref: '#/components/schemas/nested.foo.Tea'
        nested.foo.Tea:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
            self:
              $ref: '#/components/schemas/nested.foo.Tea'
            optional:
              type: array
              items:
                $ref: '#/components/schemas/optional'
        nested.foo.TeaClone:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
            self:
              $ref: '#/components/schemas/nested.foo.Tea'
            optional:
              type: array
              items:
                $ref: '#/components/schemas/optional'
        nested.foo.List:
          type: array
          items:
            $ref: '#/components/schemas/nested.foo.Tea'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  _internal

    from __future__ import annotations

    from typing import TYPE_CHECKING

    from pydantic import BaseModel, RootModel

    if TYPE_CHECKING:
        from . import models


    class Optional(RootModel[str]):
        root: str


    class Id(RootModel[str]):
        root: str


    class Error(BaseModel):
        code: int
        message: str


    class Result(BaseModel):
        event: models.Event | None = None


    class Source(BaseModel):
        country: str | None = None


    class DifferentTea(BaseModel):
        foo: Tea | None = None
        nested: Tea_1 | None = None


    class Tea(BaseModel):
        flavour: str | None = None
        id: Id | None = None


    class Cocoa(BaseModel):
        quality: int | None = None


    class Tea_1(BaseModel):
        flavour: str | None = None
        id: Id | None = None
        self: Tea_1 | None = None
        optional: list[Optional] | None = None


    class TeaClone(BaseModel):
        flavour: str | None = None
        id: Id | None = None
        self: Tea_1 | None = None
        optional: list[Optional] | None = None


    class List(RootModel[list[Tea_1]]):
        root: list[Tea_1]


    Tea_1.model_rebuild()
    ```

    <!-- fmt: on -->

---

## `--validators` {#validators}

Add custom field validators to generated Pydantic v2 models.

The `--validators` option takes an inline JSON object or JSON file defining validators per model.
Each validator specifies the field(s) to validate, the validation function
to import, and optionally the mode (before/after/wrap/plain).
This allows injecting custom validation logic into generated models.

**See also:** [Field Validators](../validators.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input field_validators.json --validators tests/data/jsonschema/field_validators_config.json --output-model-type pydantic_v2.BaseModel --use-annotated --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--validators` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "User",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "email": {
          "type": "string",
          "format": "email"
        },
        "age": {
          "type": "integer",
          "minimum": 0
        }
      },
      "required": ["name", "email"]
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  field_validators.json

    from __future__ import annotations

    from typing import Annotated, Any

    from myapp.validators import validate_email, validate_name
    from pydantic import BaseModel, EmailStr, Field, ValidationInfo, field_validator


    class User(BaseModel):
        name: str
        email: EmailStr
        age: Annotated[int | None, Field(ge=0)] = None

        @field_validator('name', mode='before')
        @classmethod
        def validate_name_validator(cls, v: Any, info: ValidationInfo) -> Any:
            return validate_name(v, info)

        @field_validator('email', mode='after')
        @classmethod
        def validate_email_validator(cls, v: Any, info: ValidationInfo) -> Any:
            return validate_email(v, info)
    ```

    <!-- fmt: on -->

---

## `--wrap-string-literal` {#wrap-string-literal}

Wrap long string literals across multiple lines.

The `--wrap-string-literal` flag breaks long string literals (like descriptions)
across multiple lines for better readability, instead of having very long
single-line strings in the generated code.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input long_description.json --wrap-string-literal # (1)!
    ```

    1. :material-arrow-left: `--wrap-string-literal` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "LongDescription",
      "type": "object",
      "properties": {
        "summary": {
          "type": "string",
          "description": "summary for object"
        },
        "description": {
          "type": "string",
          "description": "datamodel-code-generator. This code generator creates pydantic model from an openapi file and others."
        },
        "multi_line": {
          "description": "datamodel-code-generator\nThis code generator creates pydantic model from an openapi file and others.\n\n\nSupported source types\nOpenAPI 3 (YAML/JSON, OpenAPI Data Type)\nJSON Schema (JSON Schema Core/JSON Schema Validation)\nJSON/YAML/CSV Data (it will be converted to JSON Schema)\nPython dictionary (it will be converted to JSON Schema)",
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  long_description.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, Field


    class LongDescription(BaseModel):
        summary: str | None = Field(None, description='summary for object')
        description: str | None = Field(
            None,
            description=(
                'datamodel-code-generator. This code generator creates pydantic model from'
                ' an openapi file and others.'
            ),
        )
        multi_line: str | None = Field(
            None,
            description=(
                'datamodel-code-generator\nThis code generator creates pydantic model from'
                ' an openapi file and others.\n\n\nSupported source types\nOpenAPI 3'
                ' (YAML/JSON, OpenAPI Data Type)\nJSON Schema (JSON Schema Core/JSON Schema'
                ' Validation)\nJSON/YAML/CSV Data (it will be converted to JSON'
                ' Schema)\nPython dictionary (it will be converted to JSON Schema)'
            ),
        )
    ```

    <!-- fmt: on -->

---

---

# OpenAPI-only Options

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/openapi-only-options/

This generated reference lists every OpenAPI-only CLI flag and its tested examples. For a workflow-oriented guide, see [OpenAPI Options](../openapi-options.md). For input format basics, see [Generate from OpenAPI](../openapi.md).

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--include-path-parameters`](#include-path-parameters) | Include OpenAPI path parameters in generated parameter model... |
| [`--openapi-include-info-version`](#openapi-include-info-version) | Emit OpenAPI info.version as a generated constant. |
| [`--openapi-include-paths`](#openapi-include-paths) | Filter OpenAPI paths to include in model generation. |
| [`--openapi-scopes`](#openapi-scopes) | Specify OpenAPI scopes to generate (schemas, paths, paramete... |
| [`--read-only-write-only-model-type`](#read-only-write-only-model-type) | Generate separate request and response models for readOnly/w... |
| [`--use-operation-id-as-name`](#use-operation-id-as-name) | Use OpenAPI operationId as the generated function/class name... |
| [`--use-status-code-in-response-name`](#use-status-code-in-response-name) | Include HTTP status code in response model names. |
| [`--validation`](#validation) | Enable validation constraints (deprecated, use --field-const... |

---

## 🍳 Recipes

### Generate operation-focused models

Limit OpenAPI output to operation shapes and name models from operation IDs and status codes.

**Options:** [`--openapi-scopes`](#openapi-scopes), [`--use-operation-id-as-name`](#use-operation-id-as-name), [`--use-status-code-in-response-name`](#use-status-code-in-response-name)

### Trim an OpenAPI build

Restrict generation to selected paths while preserving parameter and info-version context.

**Options:** [`--openapi-include-paths`](#openapi-include-paths), [`--include-path-parameters`](#include-path-parameters), [`--openapi-include-info-version`](#openapi-include-info-version)

---

## `--include-path-parameters` {#include-path-parameters}

Include OpenAPI path parameters in generated parameter models.

The `--include-path-parameters` flag adds path parameters (like /users/{userId})
to the generated request parameter models. By default, only query parameters
are included. Use this with `--openapi-scopes parameters` to generate parameter
models that include both path and query parameters.

**See also:** [OpenAPI Options](../openapi-options.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input include_path_parameters.yaml --include-path-parameters --openapi-scopes schemas paths parameters # (1)!
    ```

    1. :material-arrow-left: `--include-path-parameters` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: API with Path Parameters
    paths:
      /users/{userId}/posts/{postId}:
        get:
          summary: Get a specific post by user
          operationId: getUserPost
          parameters:
            - name: userId
              in: path
              required: true
              schema:
                type: integer
            - name: postId
              in: path
              required: true
              schema:
                type: string
            - name: includeComments
              in: query
              required: false
              schema:
                type: boolean
          responses:
            '200':
              description: A post
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Post"
    components:
      schemas:
        Post:
          type: object
          properties:
            id:
              type: string
            title:
              type: string
            content:
              type: string
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  include_path_parameters.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Post(BaseModel):
        id: str | None = None
        title: str | None = None
        content: str | None = None


    class UsersUserIdPostsPostIdGetParameters(BaseModel):
        userId: int
        postId: str
        includeComments: bool | None = None
    ```

    <!-- fmt: on -->

---

## `--openapi-include-info-version` {#openapi-include-info-version}

Emit OpenAPI info.version as a generated constant.

The `--openapi-include-info-version` flag adds `OPENAPI_INFO_VERSION` to the
generated module so applications can check the source OpenAPI document version
at build time or runtime.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --openapi-include-info-version # (1)!
    ```

    1. :material-arrow-left: `--openapi-include-info-version` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel

    OPENAPI_INFO_VERSION = '1.0.0'


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

## `--openapi-include-paths` {#openapi-include-paths}

Filter OpenAPI paths to include in model generation.

The `--openapi-include-paths` flag allows filtering which paths are processed.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input body_and_parameters.yaml --openapi-scopes paths schemas --openapi-include-paths /pets* # (1)!
    ```

    1. :material-arrow-left: `--openapi-include-paths` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
      description: |
        This description is for testing
        multi-line
        description

    servers:
      - url: http://petstore.swagger.io/v1
    security:
      - BearerAuth: []
    paths:
      /pets:
        $ref: '#/components/pathItems/Pets'
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pet"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        put:
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          summary: update a pet
          tags:
            - pets
          requestBody:
            required: false
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/PetForm'
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
      /food:
        post:
          summary: Create a food
          tags:
            - pets
          requestBody:
            required: true
            content:
              application/problem+json:
                schema:
                  type: string
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/problem+json:
                  schema:
                    type: string
      /food/{food_id}:
        get:
          summary: Info for a specific pet
          operationId: showFoodById
          tags:
            - foods
          parameters:
            - name: food_id
              in: path
              description: The id of the food to retrieve
              schema:
                type: string
            - name: message_texts
              in: query
              required: false
              explode: true
              schema:
                type: array
                items:
                  type: string
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: array
                    items:
                      type: integer
                  examples:
                    example-1:
                      value:
                        - 0
                        - 1
                        - 3
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
      /foo:
        get:
          tags:
            - foo
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: string
        parameters:
        - $ref: '#/components/parameters/MyParam'
      /bar:
        post:
          summary: Create a bar
          tags:
            - bar
          requestBody:
            content:
              application/x-www-form-urlencoded:
                schema:
                  $ref: '#/components/schemas/PetForm'
      /user:
        get:
          tags:
            - user
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      timestamp:
                        type: string
                        format: date-time
                      name:
                        type: string
                      age:
                        type: string
                    required:
                      - name
                      - timestamp
        post:
          tags:
            - user
          requestBody:
            required: true
            content:
              application/json:
                schema:
                  type: object
                  properties:
                    timestamp:
                      type: string
                      format: date-time
                    name:
                      type: string
                    age:
                      type: string
                  required:
                    - name
                    - timestamp
          responses:
            '201':
              description: OK
      /users:
        get:
          tags:
            - user
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: array
                    items:
                      type: object
                      properties:
                        timestamp:
                          type: string
                          format: date-time
                        name:
                          type: string
                        age:
                          type: string
                      required:
                        - name
                        - timestamp
        post:
          tags:
            - user
          requestBody:
            required: true
            content:
              application/json:
                schema:
                  type: array
                  items:
                    type: object
                    properties:
                      timestamp:
                        type: string
                        format: date-time
                      name:
                        type: string
                      age:
                        type: string
                    required:
                      - name
                      - timestamp
          responses:
            '201':
              description: OK
    components:
      parameters:
        MyParam:
          name: foo
          in: query
          schema:
            type: string
      securitySchemes:
        BearerAuth:
          type: http
          scheme: bearer
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        PetForm:
          title: PetForm
          type: object
          properties:
            name:
              type: string
            age:
              type: integer
      pathItems:
        Pets:
          get:
            summary: List all pets
            operationId: listPets
            tags:
              - pets
            security: []
            parameters:
              - name: limit
                in: query
                description: How many items to return at one time (max 100)
                required: false
                schema:
                  default: 0
                  type: integer
                  format: int32
              - name: HomeAddress
                in: query
                required: false
                schema:
                  default: 'Unknown'
                  type: string
              - name: kind
                in: query
                required: false
                schema:
                  default: dog
                  type: string
            responses:
              '200':
                description: A paged array of pets
                headers:
                  x-next:
                    description: A link to the next page of responses
                    schema:
                      type: string
                content:
                  application/json:
                    schema:
                      type: array
                      items:
                      - $ref: "#/components/schemas/Pet"
              default:
                description: unexpected error
                content:
                  application/json:
                    schema:
                      $ref: "#/components/schemas/Error"
          post:
            summary: Create a pet
            tags:
              - pets
            requestBody:
              required: true
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/PetForm'
            responses:
              '201':
                description: Null response
              default:
                description: unexpected error
                content:
                  application/json:
                    schema:
                      $ref: "#/components/schemas/Error"
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  body_and_parameters.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Error(BaseModel):
        code: int
        message: str


    class PetForm(BaseModel):
        name: str | None = None
        age: int | None = None


    class PetsGetResponse(RootModel[list[Pet]]):
        root: list[Pet]
    ```

    <!-- fmt: on -->

---

## `--openapi-scopes` {#openapi-scopes}

Specify OpenAPI scopes to generate (schemas, paths, parameters).

The `--openapi-scopes` flag configures the code generation behavior.

**See also:** [OpenAPI Options](../openapi-options.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input body_and_parameters.yaml --openapi-scopes paths schemas # (1)!
    ```

    1. :material-arrow-left: `--openapi-scopes` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
      description: |
        This description is for testing
        multi-line
        description

    servers:
      - url: http://petstore.swagger.io/v1
    security:
      - BearerAuth: []
    paths:
      /pets:
        $ref: '#/components/pathItems/Pets'
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pet"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        put:
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          summary: update a pet
          tags:
            - pets
          requestBody:
            required: false
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/PetForm'
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
      /food:
        post:
          summary: Create a food
          tags:
            - pets
          requestBody:
            required: true
            content:
              application/problem+json:
                schema:
                  type: string
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/problem+json:
                  schema:
                    type: string
      /food/{food_id}:
        get:
          summary: Info for a specific pet
          operationId: showFoodById
          tags:
            - foods
          parameters:
            - name: food_id
              in: path
              description: The id of the food to retrieve
              schema:
                type: string
            - name: message_texts
              in: query
              required: false
              explode: true
              schema:
                type: array
                items:
                  type: string
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: array
                    items:
                      type: integer
                  examples:
                    example-1:
                      value:
                        - 0
                        - 1
                        - 3
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
      /foo:
        get:
          tags:
            - foo
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: string
        parameters:
        - $ref: '#/components/parameters/MyParam'
      /bar:
        post:
          summary: Create a bar
          tags:
            - bar
          requestBody:
            content:
              application/x-www-form-urlencoded:
                schema:
                  $ref: '#/components/schemas/PetForm'
      /user:
        get:
          tags:
            - user
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      timestamp:
                        type: string
                        format: date-time
                      name:
                        type: string
                      age:
                        type: string
                    required:
                      - name
                      - timestamp
        post:
          tags:
            - user
          requestBody:
            required: true
            content:
              application/json:
                schema:
                  type: object
                  properties:
                    timestamp:
                      type: string
                      format: date-time
                    name:
                      type: string
                    age:
                      type: string
                  required:
                    - name
                    - timestamp
          responses:
            '201':
              description: OK
      /users:
        get:
          tags:
            - user
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: array
                    items:
                      type: object
                      properties:
                        timestamp:
                          type: string
                          format: date-time
                        name:
                          type: string
                        age:
                          type: string
                      required:
                        - name
                        - timestamp
        post:
          tags:
            - user
          requestBody:
            required: true
            content:
              application/json:
                schema:
                  type: array
                  items:
                    type: object
                    properties:
                      timestamp:
                        type: string
                        format: date-time
                      name:
                        type: string
                      age:
                        type: string
                    required:
                      - name
                      - timestamp
          responses:
            '201':
              description: OK
    components:
      parameters:
        MyParam:
          name: foo
          in: query
          schema:
            type: string
      securitySchemes:
        BearerAuth:
          type: http
          scheme: bearer
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        PetForm:
          title: PetForm
          type: object
          properties:
            name:
              type: string
            age:
              type: integer
      pathItems:
        Pets:
          get:
            summary: List all pets
            operationId: listPets
            tags:
              - pets
            security: []
            parameters:
              - name: limit
                in: query
                description: How many items to return at one time (max 100)
                required: false
                schema:
                  default: 0
                  type: integer
                  format: int32
              - name: HomeAddress
                in: query
                required: false
                schema:
                  default: 'Unknown'
                  type: string
              - name: kind
                in: query
                required: false
                schema:
                  default: dog
                  type: string
            responses:
              '200':
                description: A paged array of pets
                headers:
                  x-next:
                    description: A link to the next page of responses
                    schema:
                      type: string
                content:
                  application/json:
                    schema:
                      type: array
                      items:
                      - $ref: "#/components/schemas/Pet"
              default:
                description: unexpected error
                content:
                  application/json:
                    schema:
                      $ref: "#/components/schemas/Error"
          post:
            summary: Create a pet
            tags:
              - pets
            requestBody:
              required: true
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/PetForm'
            responses:
              '201':
                description: Null response
              default:
                description: unexpected error
                content:
                  application/json:
                    schema:
                      $ref: "#/components/schemas/Error"
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  body_and_parameters.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AwareDatetime, BaseModel, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Error(BaseModel):
        code: int
        message: str


    class PetForm(BaseModel):
        name: str | None = None
        age: int | None = None


    class PetsGetResponse(RootModel[list[Pet]]):
        root: list[Pet]


    class FoodFoodIdGetResponse(RootModel[list[int]]):
        root: list[int]


    class UserGetResponse(BaseModel):
        timestamp: AwareDatetime
        name: str
        age: str | None = None


    class UserPostRequest(BaseModel):
        timestamp: AwareDatetime
        name: str
        age: str | None = None


    class UsersGetResponseItem(BaseModel):
        timestamp: AwareDatetime
        name: str
        age: str | None = None


    class UsersGetResponse(RootModel[list[UsersGetResponseItem]]):
        root: list[UsersGetResponseItem]


    class UsersPostRequestItem(BaseModel):
        timestamp: AwareDatetime
        name: str
        age: str | None = None


    class UsersPostRequest(RootModel[list[UsersPostRequestItem]]):
        root: list[UsersPostRequestItem]
    ```

    <!-- fmt: on -->

---

## `--read-only-write-only-model-type` {#read-only-write-only-model-type}

Generate separate request and response models for readOnly/writeOnly fields.

The `--read-only-write-only-model-type` option controls how models with readOnly or writeOnly
properties are generated. The 'request-response' mode creates separate Request and Response
variants for each schema that contains readOnly or writeOnly fields, allowing proper type
validation for API requests and responses without a shared base model.

**See also:** [OpenAPI Options](../openapi-options.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input read_only_write_only.yaml --output-model-type pydantic_v2.BaseModel --read-only-write-only-model-type request-response # (1)!
    ```

    1. :material-arrow-left: `--read-only-write-only-model-type` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      title: Read Only Write Only Test API
      version: "1.0"
    paths: {}
    components:
      schemas:
        User:
          type: object
          required:
            - id
            - name
            - password
          properties:
            id:
              type: integer
              readOnly: true
            name:
              type: string
            password:
              type: string
              writeOnly: true
            created_at:
              type: string
              format: date-time
              readOnly: true
            secret_token:
              type: string
              writeOnly: true
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  read_only_write_only.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AwareDatetime, BaseModel


    class UserRequest(BaseModel):
        name: str
        password: str
        secret_token: str | None = None


    class UserResponse(BaseModel):
        id: int
        name: str
        created_at: AwareDatetime | None = None
    ```

    <!-- fmt: on -->

---

## `--use-operation-id-as-name` {#use-operation-id-as-name}

Use OpenAPI operationId as the generated function/class name.

The `--use-operation-id-as-name` flag configures the code generation behavior.

**See also:** [OpenAPI Options](../openapi-options.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --use-operation-id-as-name --openapi-scopes paths schemas parameters # (1)!
    ```

    1. :material-arrow-left: `--use-operation-id-as-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None


    class ListPetsParametersQuery(BaseModel):
        limit: int | None = None
    ```

    <!-- fmt: on -->

---

## `--use-status-code-in-response-name` {#use-status-code-in-response-name}

Include HTTP status code in response model names.

The `--use-status-code-in-response-name` flag includes the HTTP status code
in generated response model class names. Instead of generating ambiguous names
like ResourceGetResponse, ResourceGetResponse1, ResourceGetResponse2, it generates
clear names like ResourceGetResponse200, ResourceGetResponse400, ResourceGetResponseDefault.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input use_status_code_in_response_name.yaml --use-status-code-in-response-name --openapi-scopes schemas paths # (1)!
    ```

    1. :material-arrow-left: `--use-status-code-in-response-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Status Code Response Name Test API
    paths:
      /resource:
        get:
          summary: Get a resource
          responses:
            '200':
              description: Successful response
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
            '400':
              description: Bad request error
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      error:
                        type: string
                      code:
                        type: integer
            'default':
              description: Unexpected error
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      message:
                        type: string
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  use_status_code_in_response_name.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class ResourceGetResponse200(BaseModel):
        id: int | None = None
        name: str | None = None


    class ResourceGetResponse400(BaseModel):
        error: str | None = None
        code: int | None = None


    class ResourceGetResponseDefault(BaseModel):
        message: str | None = None
    ```

    <!-- fmt: on -->

---

## `--validation` {#validation}

Enable validation constraints (deprecated, use --field-constraints).

The `--validation` flag configures the code generation behavior.

**Deprecated:** The `--validation` option is deprecated and will be removed in a future release. Use --field-constraints instead.

**See also:** [OpenAPI Options](../openapi-options.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input api.yaml --validation # (1)!
    ```

    1. :material-arrow-left: `--validation` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
              default: 1
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          items:
            $ref: "#/components/schemas/Pet"
        Users:
          type: array
          items:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
        Id:
          type: string
        Rules:
          type: array
          items:
            type: string
        Error:
          description: error result
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
        Event:
          type: object
          description: Event object
          properties:
            name:
              type: string
        Result:
            type: object
            properties:
              event:
                $ref: '#/components/schemas/Event'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  api.yaml
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import AnyUrl, BaseModel, Field, RootModel


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Pets(RootModel[list[Pet]]):
        root: list[Pet]


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Users(RootModel[list[User]]):
        root: list[User]


    class Id(RootModel[str]):
        root: str


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Error(BaseModel):
        code: int
        message: str


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )


    class Apis(RootModel[list[Api]]):
        root: list[Api]


    class Event(BaseModel):
        name: str | None = None


    class Result(BaseModel):
        event: Event | None = None
    ```

    <!-- fmt: on -->

---

---

# GraphQL-only Options

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/graphql-only-options/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--graphql-no-typename`](#graphql-no-typename) | Exclude __typename field from generated GraphQL models. |

---

## 🍳 Recipes

### Trim GraphQL metadata fields

Skip injected typename fields when generated models should expose only business data.

**Options:** [`--graphql-no-typename`](#graphql-no-typename)

---

## `--graphql-no-typename` {#graphql-no-typename}

Exclude __typename field from generated GraphQL models.

The `--graphql-no-typename` flag prevents the generator from adding the
`typename__` field (aliased to `__typename`) to generated models. This is
useful when using generated models for GraphQL mutations, as servers typically
don't expect this field in input data.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input no-typename.graphql --graphql-no-typename # (1)!
    ```

    1. :material-arrow-left: `--graphql-no-typename` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```graphql
    type Book {
      id: ID!
      title: String
    }

    interface Node {
      id: ID!
    }

    input BookInput {
      title: String!
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  no-typename.graphql
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel
    from typing_extensions import TypeAliasType

    Boolean = TypeAliasType("Boolean", bool)
    """
    The `Boolean` scalar type represents `true` or `false`.
    """


    ID = TypeAliasType("ID", str)
    """
    The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
    """


    String = TypeAliasType("String", str)
    """
    The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
    """


    class Node(BaseModel):
        id: ID


    class Book(BaseModel):
        id: ID
        title: String | None = None


    class BookInput(BaseModel):
        title: String
    ```

    <!-- fmt: on -->

---

---

# General Options

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/general-options/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--all-exports-collision-strategy`](#all-exports-collision-strategy) | Handle name collisions when exporting recursive module hiera... |
| [`--all-exports-scope`](#all-exports-scope) | Generate __all__ exports for child modules in __init__.py fi... |
| [`--allow-private-network`](#allow-private-network) | Allow HTTP requests to private network schema endpoints. |
| [`--allow-remote-refs`](#allow-remote-refs) | Enable fetching of `$ref` targets over HTTP/HTTPS. |
| [`--check`](#check) | Verify generated code matches existing output without modify... |
| [`--diff-against`](#diff-against) | Compare generated code from a baseline input with the curren... |
| [`--disable-warnings`](#disable-warnings) | Suppress warning messages during code generation. |
| [`--fail-on-multi-module-stdout`](#fail-on-multi-module-stdout) | Fail instead of concatenating multiple modules in text stdou... |
| [`--generate-cli-command`](#generate-cli-command) | Generate CLI command from pyproject.toml configuration. |
| [`--generate-pyproject-config`](#generate-pyproject-config) | Generate pyproject.toml configuration from CLI arguments. |
| [`--http-headers`](#http-headers) | Fetch a schema from a URL with custom HTTP headers. |
| [`--http-ignore-tls`](#http-ignore-tls) | Disable TLS certificate verification for HTTPS requests. |
| [`--http-local-ref-path`](#http-local-ref-path) | Resolve HTTP references from local schema files. |
| [`--http-query-parameters`](#http-query-parameters) | Add query parameters to HTTP requests for remote schemas. |
| [`--http-timeout`](#http-timeout) | Set timeout for HTTP requests to remote hosts. |
| [`--ignore-pyproject`](#ignore-pyproject) | Ignore pyproject.toml configuration file. |
| [`--locked`](#locked) | Require an existing remote lock and validate each fetched re... |
| [`--lockfile`](#lockfile) | Select the remote reference integrity lock file (experimenta... |
| [`--module-split-mode`](#module-split-mode) | Split generated models into separate files, one per model cl... |
| [`--shared-module-name`](#shared-module-name) | Customize the name of the shared module for deduplicated mod... |
| [`--strict-refs`](#strict-refs) | Treat unresolved local `$ref` JSON pointers as errors. |
| [`--update-lock`](#update-lock) | Create or atomically update the selected remote lock after g... |
| [`--watch`](#watch) | Watch input file(s) for changes and regenerate output automa... |
| [`--watch-delay`](#watch-delay) | Set debounce delay in seconds for watch mode. |

---

## 🍳 Recipes

### Resolve remote references deliberately

Enable remote `$ref` loading and configure request metadata, timeouts, or local ref roots.

**Options:** [`--allow-remote-refs`](#allow-remote-refs), [`--http-headers`](#http-headers), [`--http-timeout`](#http-timeout), [`--http-local-ref-path`](#http-local-ref-path)

### Regenerate during schema edits

Watch input files with a short debounce while writing output to a stable target path.

**Options:** [`--watch`](#watch), [`--watch-delay`](#watch-delay), [`--output`](base-options.md#output)

---

## `--all-exports-collision-strategy` {#all-exports-collision-strategy}

Handle name collisions when exporting recursive module hierarchies.

The `--all-exports-collision-strategy` flag determines how to resolve naming conflicts
when using `--all-exports-scope=recursive`. The 'minimal-prefix' strategy adds the
minimum module path prefix needed to disambiguate colliding names, while 'full-prefix'
uses the complete module path. Requires `--all-exports-scope=recursive`.

**Related:** [`--all-exports-scope`](#all-exports-scope)

**See also:** [Module Structure and Exports](../module-exports.md)

**Option relationships:**

- **Requires:** [`--all-exports-scope`](general-options.md#all-exports-scope) = `recursive` - `--all-exports-collision-strategy` can only be used with `--all-exports-scope=recursive`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input modular.yaml --all-exports-scope recursive --all-exports-collision-strategy minimal-prefix # (1)!
    ```

    1. :material-arrow-left: `--all-exports-collision-strategy` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Modular Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/collections.Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/collections.Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        models.Species:
          type: string
          enum:
            - dog
            - cat
            - snake
        models.Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
            species:
              $ref: '#/components/schemas/models.Species'
        models.User:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
        collections.Pets:
          type: array
          items:
            $ref: "#/components/schemas/models.Pet"
        collections.Users:
          type: array
          items:
            $ref: "#/components/schemas/models.User"
        optional:
          type: string
        Id:
          type: string
        collections.Rules:
          type: array
          items:
            type: string
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        collections.apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
              stage:
                type: string
                enum: [
                  "test",
                  "dev",
                  "stg",
                  "prod"
                ]
        models.Event:
          type: object
          properties:
            name:
              anyOf:
                - type: string
                - type: number
                - type: integer
                - type: boolean
                - type: object
                - type: array
                  items:
                    type: string
        Result:
          type: object
          properties:
            event:
              $ref: '#/components/schemas/models.Event'
        foo.bar.Thing:
          properties:
            attributes:
              type: object
        foo.bar.Thang:
          properties:
            attributes:
              type: array
              items:
                type: object
        foo.bar.Clone:
          allOf:
            - $ref: '#/components/schemas/foo.bar.Thing'
            - type: object
              properties:
                others:
                  type: object
                  properties:
                     name:
                       type: string

        foo.Tea:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
        Source:
          properties:
            country:
              type: string
        foo.Cocoa:
          properties:
            quality:
              type: integer
        bar.Field:
          type: string
          example: green
        woo.boo.Chocolate:
          properties:
            flavour:
              type: string
            source:
              $ref: '#/components/schemas/Source'
            cocoa:
              $ref: '#/components/schemas/foo.Cocoa'
            field:
              $ref: '#/components/schemas/bar.Field'
        differentTea:
          type: object
          properties:
            foo:
              $ref: '#/components/schemas/foo.Tea'
            nested:
              $ref: '#/components/schemas/nested.foo.Tea'
        nested.foo.Tea:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
            self:
              $ref: '#/components/schemas/nested.foo.Tea'
            optional:
              type: array
              items:
                $ref: '#/components/schemas/optional'
        nested.foo.TeaClone:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
            self:
              $ref: '#/components/schemas/nested.foo.Tea'
            optional:
              type: array
              items:
                $ref: '#/components/schemas/optional'
        nested.foo.List:
          type: array
          items:
            $ref: '#/components/schemas/nested.foo.Tea'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # __init__.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from ._internal import DifferentTea, Error, Id, Optional, Result, Source

    __all__ = ["DifferentTea", "Error", "Id", "Optional", "Result", "Source"]

    # _internal.py
    # generated by datamodel-codegen:
    #   filename:  _internal

    from __future__ import annotations

    from pydantic import BaseModel, RootModel

    from . import models


    class Optional(RootModel[str]):
        root: str


    class Id(RootModel[str]):
        root: str


    class Error(BaseModel):
        code: int
        message: str


    class Result(BaseModel):
        event: models.Event | None = None


    class Source(BaseModel):
        country: str | None = None


    class DifferentTea(BaseModel):
        foo: Tea | None = None
        nested: Tea_1 | None = None


    class Tea(BaseModel):
        flavour: str | None = None
        id: Id | None = None


    class Cocoa(BaseModel):
        quality: int | None = None


    class Tea_1(BaseModel):
        flavour: str | None = None
        id: Id | None = None
        self: Tea_1 | None = None
        optional: list[Optional] | None = None


    class TeaClone(BaseModel):
        flavour: str | None = None
        id: Id | None = None
        self: Tea_1 | None = None
        optional: list[Optional] | None = None


    class List(RootModel[list[Tea_1]]):
        root: list[Tea_1]


    Tea_1.model_rebuild()

    # bar.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from pydantic import Field, RootModel


    class FieldModel(RootModel[str]):
        root: str = Field(..., examples=['green'])

    # collections.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from enum import Enum

    from pydantic import AnyUrl, BaseModel, Field, RootModel

    from . import models


    class Pets(RootModel[list[models.Pet]]):
        root: list[models.Pet]


    class Users(RootModel[list[models.User]]):
        root: list[models.User]


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Stage(Enum):
        test = 'test'
        dev = 'dev'
        stg = 'stg'
        prod = 'prod'


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )
        stage: Stage | None = None


    class Apis(RootModel[list[Api]]):
        root: list[Api]

    # foo/__init__.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from .._internal import Cocoa, Tea

    __all__ = ["Cocoa", "Tea"]

    # foo/bar.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel


    class Thing(BaseModel):
        attributes: dict[str, Any] | None = None


    class Thang(BaseModel):
        attributes: list[dict[str, Any]] | None = None


    class Others(BaseModel):
        name: str | None = None


    class Clone(Thing):
        others: Others | None = None

    # models.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from enum import Enum
    from typing import Any

    from pydantic import BaseModel


    class Species(Enum):
        dog = 'dog'
        cat = 'cat'
        snake = 'snake'


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None
        species: Species | None = None


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Event(BaseModel):
        name: str | float | int | bool | dict[str, Any] | list[str] | None = None

    # nested/__init__.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    # nested/foo.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from .._internal import List
    from .._internal import Tea_1 as Tea
    from .._internal import TeaClone

    __all__ = ["List", "Tea", "TeaClone"]

    # woo/__init__.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from .boo import Chocolate

    __all__ = [
        "Chocolate",
    ]

    # woo/boo.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from pydantic import BaseModel

    from .. import bar
    from .._internal import Cocoa, Source


    class Chocolate(BaseModel):
        flavour: str | None = None
        source: Source | None = None
        cocoa: Cocoa | None = None
        field: bar.FieldModel | None = None
    ```

    <!-- fmt: on -->

---

## `--all-exports-scope` {#all-exports-scope}

Generate __all__ exports for child modules in __init__.py files.

The `--all-exports-scope=children` flag adds __all__ to each __init__.py containing
exports from direct child modules. This improves IDE autocomplete and explicit exports.
Use 'recursive' to include all descendant exports with collision handling.

**Related:** [`--all-exports-collision-strategy`](#all-exports-collision-strategy)

**See also:** [Module Structure and Exports](../module-exports.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input modular.yaml --all-exports-scope children # (1)!
    ```

    1. :material-arrow-left: `--all-exports-scope` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Modular Swagger Petstore
      license:
        name: MIT
    servers:
      - url: http://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/collections.Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
                    x-amazon-apigateway-integration:
                      uri:
                        Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                      passthroughBehavior: when_no_templates
                      httpMethod: POST
                      type: aws_proxy
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/collections.Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        x-amazon-apigateway-integration:
          uri:
            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
          passthroughBehavior: when_no_templates
          httpMethod: POST
          type: aws_proxy
    components:
      schemas:
        models.Species:
          type: string
          enum:
            - dog
            - cat
            - snake
        models.Pet:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
            species:
              $ref: '#/components/schemas/models.Species'
        models.User:
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
        collections.Pets:
          type: array
          items:
            $ref: "#/components/schemas/models.Pet"
        collections.Users:
          type: array
          items:
            $ref: "#/components/schemas/models.User"
        optional:
          type: string
        Id:
          type: string
        collections.Rules:
          type: array
          items:
            type: string
        Error:
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string
        collections.apis:
          type: array
          items:
            type: object
            properties:
              apiKey:
                type: string
                description: To be used as a dataset parameter value
              apiVersionNumber:
                type: string
                description: To be used as a version parameter value
              apiUrl:
                type: string
                format: uri
                description: "The URL describing the dataset's fields"
              apiDocumentationUrl:
                type: string
                format: uri
                description: A URL to the API console for each API
              stage:
                type: string
                enum: [
                  "test",
                  "dev",
                  "stg",
                  "prod"
                ]
        models.Event:
          type: object
          properties:
            name:
              anyOf:
                - type: string
                - type: number
                - type: integer
                - type: boolean
                - type: object
                - type: array
                  items:
                    type: string
        Result:
          type: object
          properties:
            event:
              $ref: '#/components/schemas/models.Event'
        foo.bar.Thing:
          properties:
            attributes:
              type: object
        foo.bar.Thang:
          properties:
            attributes:
              type: array
              items:
                type: object
        foo.bar.Clone:
          allOf:
            - $ref: '#/components/schemas/foo.bar.Thing'
            - type: object
              properties:
                others:
                  type: object
                  properties:
                     name:
                       type: string

        foo.Tea:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
        Source:
          properties:
            country:
              type: string
        foo.Cocoa:
          properties:
            quality:
              type: integer
        bar.Field:
          type: string
          example: green
        woo.boo.Chocolate:
          properties:
            flavour:
              type: string
            source:
              $ref: '#/components/schemas/Source'
            cocoa:
              $ref: '#/components/schemas/foo.Cocoa'
            field:
              $ref: '#/components/schemas/bar.Field'
        differentTea:
          type: object
          properties:
            foo:
              $ref: '#/components/schemas/foo.Tea'
            nested:
              $ref: '#/components/schemas/nested.foo.Tea'
        nested.foo.Tea:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
            self:
              $ref: '#/components/schemas/nested.foo.Tea'
            optional:
              type: array
              items:
                $ref: '#/components/schemas/optional'
        nested.foo.TeaClone:
          properties:
            flavour:
              type: string
            id:
              $ref: '#/components/schemas/Id'
            self:
              $ref: '#/components/schemas/nested.foo.Tea'
            optional:
              type: array
              items:
                $ref: '#/components/schemas/optional'
        nested.foo.List:
          type: array
          items:
            $ref: '#/components/schemas/nested.foo.Tea'
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # __init__.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from ._internal import DifferentTea, Error, Id, Optional, Result, Source

    __all__ = ["DifferentTea", "Error", "Id", "Optional", "Result", "Source"]

    # _internal.py
    # generated by datamodel-codegen:
    #   filename:  _internal

    from __future__ import annotations

    from pydantic import BaseModel, RootModel

    from . import models


    class Optional(RootModel[str]):
        root: str


    class Id(RootModel[str]):
        root: str


    class Error(BaseModel):
        code: int
        message: str


    class Result(BaseModel):
        event: models.Event | None = None


    class Source(BaseModel):
        country: str | None = None


    class DifferentTea(BaseModel):
        foo: Tea | None = None
        nested: Tea_1 | None = None


    class Tea(BaseModel):
        flavour: str | None = None
        id: Id | None = None


    class Cocoa(BaseModel):
        quality: int | None = None


    class Tea_1(BaseModel):
        flavour: str | None = None
        id: Id | None = None
        self: Tea_1 | None = None
        optional: list[Optional] | None = None


    class TeaClone(BaseModel):
        flavour: str | None = None
        id: Id | None = None
        self: Tea_1 | None = None
        optional: list[Optional] | None = None


    class List(RootModel[list[Tea_1]]):
        root: list[Tea_1]


    Tea_1.model_rebuild()

    # bar.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from pydantic import Field, RootModel


    class FieldModel(RootModel[str]):
        root: str = Field(..., examples=['green'])

    # collections.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from enum import Enum

    from pydantic import AnyUrl, BaseModel, Field, RootModel

    from . import models


    class Pets(RootModel[list[models.Pet]]):
        root: list[models.Pet]


    class Users(RootModel[list[models.User]]):
        root: list[models.User]


    class Rules(RootModel[list[str]]):
        root: list[str]


    class Stage(Enum):
        test = 'test'
        dev = 'dev'
        stg = 'stg'
        prod = 'prod'


    class Api(BaseModel):
        apiKey: str | None = Field(
            None, description='To be used as a dataset parameter value'
        )
        apiVersionNumber: str | None = Field(
            None, description='To be used as a version parameter value'
        )
        apiUrl: AnyUrl | None = Field(
            None, description="The URL describing the dataset's fields"
        )
        apiDocumentationUrl: AnyUrl | None = Field(
            None, description='A URL to the API console for each API'
        )
        stage: Stage | None = None


    class Apis(RootModel[list[Api]]):
        root: list[Api]

    # foo/__init__.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from .._internal import Cocoa, Tea

    __all__ = ["Cocoa", "Tea"]

    # foo/bar.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel


    class Thing(BaseModel):
        attributes: dict[str, Any] | None = None


    class Thang(BaseModel):
        attributes: list[dict[str, Any]] | None = None


    class Others(BaseModel):
        name: str | None = None


    class Clone(Thing):
        others: Others | None = None

    # models.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from enum import Enum
    from typing import Any

    from pydantic import BaseModel


    class Species(Enum):
        dog = 'dog'
        cat = 'cat'
        snake = 'snake'


    class Pet(BaseModel):
        id: int
        name: str
        tag: str | None = None
        species: Species | None = None


    class User(BaseModel):
        id: int
        name: str
        tag: str | None = None


    class Event(BaseModel):
        name: str | float | int | bool | dict[str, Any] | list[str] | None = None

    # nested/__init__.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    # nested/foo.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from .._internal import List
    from .._internal import Tea_1 as Tea
    from .._internal import TeaClone

    __all__ = ["List", "Tea", "TeaClone"]

    # woo/__init__.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from .boo import Chocolate

    __all__ = [
        "Chocolate",
    ]

    # woo/boo.py
    # generated by datamodel-codegen:
    #   filename:  modular.yaml

    from __future__ import annotations

    from pydantic import BaseModel

    from .. import bar
    from .._internal import Cocoa, Source


    class Chocolate(BaseModel):
        flavour: str | None = None
        source: Source | None = None
        cocoa: Cocoa | None = None
        field: bar.FieldModel | None = None
    ```

    <!-- fmt: on -->

---

## `--allow-private-network` {#allow-private-network}

Allow HTTP requests to private network schema endpoints.

The `--allow-private-network` flag permits trusted HTTP(S) schema requests to
private, loopback, link-local, or otherwise non-public network hosts. Without
this flag, those targets are blocked by default to reduce server-side request
forgery (SSRF) risk. If a trusted internal schema endpoint is blocked, verify
the URL and pass `--allow-private-network`; otherwise use a local schema file
or public endpoint.

!!! tip "Usage"

    ```bash
    datamodel-codegen --url http://127.0.0.1/schema.json --allow-private-network # (1)!
    ```

    1. :material-arrow-left: `--allow-private-network` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  http://127.0.0.1/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--allow-remote-refs` {#allow-remote-refs}

Enable fetching of `$ref` targets over HTTP/HTTPS.

When enabled, the generator will resolve `$ref` references that point to remote URLs,
including relative refs resolved against a schema's `$id` base URL. This is required
for schemas that reference definitions hosted on external servers.

Automatically enabled when using `--url` input.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input root_id.json --allow-remote-refs # (1)!
    ```

    1. :material-arrow-left: `--allow-remote-refs` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$id": "https://example.com/root_id.json",
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "Person": {
          "$ref": "person.json"
        },
        "OriginalPerson": {
          "$ref": "person.json"
        },
        "Pet": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "examples": ["dog", "cat"]
            },
            "owner": {
               "$ref": "person.json"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  root_id.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, Field, RootModel, conint


    class Model(RootModel[Any]):
        root: Any


    class Person(BaseModel):
        firstName: str | None = Field(None, description="The person's first name.")
        lastName: str | None = Field(None, description="The person's last name.")
        age: conint(ge=0) | None = Field(
            None, description='Age in years which must be equal to or greater than zero.'
        )
        friends: list[Any] | None = None
        comment: None = Field(None)


    class OriginalPerson(RootModel[Person]):
        root: Person


    class Pet(BaseModel):
        name: str | None = Field(None, examples=['dog', 'cat'])
        owner: Person | None = None
    ```

    <!-- fmt: on -->

---

## `--check` {#check}

Verify generated code matches existing output without modifying files.

The `--check` flag compares the generated output with existing files and exits with
a non-zero status if they differ. Useful for CI/CD validation to ensure schemas
and generated code stay in sync. Works with both single files and directory outputs.

**See also:** [CI/CD Integration](../ci-cd.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --disable-timestamp --check # (1)!
    ```

    1. :material-arrow-left: `--check` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": ["string", "null"],
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  person.json

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, Field, conint


    class Person(BaseModel):
        firstName: str | None = Field(None, description="The person's first name.")
        lastName: str | None = Field(None, description="The person's last name.")
        age: conint(ge=0) | None = Field(
            None, description='Age in years which must be equal to or greater than zero.'
        )
        friends: list[Any] | None = None
        comment: None = Field(None)
    ```

    <!-- fmt: on -->

---

## `--diff-against` {#diff-against}

Compare generated code from a baseline input with the current schema without writing files.

Pass the baseline input with `--diff-against` and the current schema with `--input`.
The command generates both, then shows the generated-code diff from baseline to current.
The required `--output` value is a virtual destination: it selects single-file or
directory layout and formatter settings, but datamodel-code-generator never writes it.
The command exits non-zero when the formatted generated outputs differ, making it useful
for reviewing schema migrations in CI.

**Related:** [`--check`](#check), [`--input`](base-options.md#input), [`--output`](base-options.md#output), `--output-format`

**Option relationships:**

- **Requires:** [`--input`](base-options.md#input) - `--diff-against` requires --input with the current local schema path.
- **Requires:** [`--output`](base-options.md#output) - `--diff-against` requires --output to select file or directory output layout.
- **Conflicts:** [`--check`](general-options.md#check)
- **Conflicts:** [`--watch`](general-options.md#watch)
- **Conflicts:** [`--url`](base-options.md#url)
- **Conflicts:** [`--input-model`](base-options.md#input-model)
- **Conflicts:** [`--emit-model-metadata`](base-options.md#emit-model-metadata)
- **Conflicts:** [`--fail-on-multi-module-stdout`](general-options.md#fail-on-multi-module-stdout)
- **Conflicts:** `--job` - `--diff-against` compares one profile or input and cannot run named jobs.
- **Conflicts:** `--all-jobs` - `--diff-against` compares one profile or input and cannot run named jobs.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input tests/data/openapi/input_diff/new.yaml --diff-against tests/data/openapi/input_diff/old.yaml --output models --input-file-type openapi --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--diff-against` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.0.0
    info:
      title: Current models
      version: "1.0"
    paths: {}
    components:
      schemas:
        collections.Current:
          type: object
          properties:
            name:
              type: string
    ```

    **Output:**

    <!-- fmt: off -->

    ```
    ADDED: collections.py (generated only from current input)
    REMOVED: models.py (generated only from baseline input)
    ```

    <!-- fmt: on -->

---

## `--disable-warnings` {#disable-warnings}

Suppress warning messages during code generation.

The --disable-warnings option silences all warning messages that the generator
might emit during processing (e.g., about unsupported features, ambiguous schemas,
or potential issues). Useful for clean output in CI/CD pipelines.

**See also:** [Model Reuse and Deduplication](../model-reuse.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input all_of_with_object.json --disable-warnings # (1)!
    ```

    1. :material-arrow-left: `--disable-warnings` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "allOf": [
        {
          "$ref": "#/definitions/Home"
        },
        {
          "$ref": "#/definitions/Kind"
        },
        {
          "$ref": "#/definitions/Id"
        },
        {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      ],
      "type": [
        "object"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        }
      },
      "definitions": {
        "Home": {
          "type": "object",
          "properties": {
            "address": {
              "type": "string"
            },
            "zip": {
              "type": "string"
            }
          }
        },
        "Kind": {
          "type": "object",
          "properties": {
            "description": {
              "type": "string"
            }
          }
        },
        "Id": {
          "type": "object",
          "properties": {
            "id": {
              "type": "integer"
            }
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  all_of_with_object.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Home(BaseModel):
        address: str | None = None
        zip: str | None = None


    class Kind(BaseModel):
        description: str | None = None


    class Id(BaseModel):
        id: int | None = None


    class Pet(Home, Kind, Id):
        name: str | None = None
        age: int | None = None
    ```

    <!-- fmt: on -->

---

## `--fail-on-multi-module-stdout` {#fail-on-multi-module-stdout}

Fail instead of concatenating multiple modules in text stdout.

The `--fail-on-multi-module-stdout` flag detects modular results while preserving
the legacy default, single-module output, JSON output, and file output. It takes
precedence over automatic unusable-stdout repair, rejecting the modular result
instead of coalescing it.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --fail-on-multi-module-stdout --disable-timestamp # (1)!
    ```

    1. :material-arrow-left: `--fail-on-multi-module-stdout` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": ["string", "null"],
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  person.json

    from __future__ import annotations

    from typing import Any

    from pydantic import BaseModel, Field, conint


    class Person(BaseModel):
        firstName: str | None = Field(None, description="The person's first name.")
        lastName: str | None = Field(None, description="The person's last name.")
        age: conint(ge=0) | None = Field(
            None, description='Age in years which must be equal to or greater than zero.'
        )
        friends: list[Any] | None = None
        comment: None = Field(None)
    ```

    <!-- fmt: on -->

---

## `--generate-cli-command` {#generate-cli-command}

Generate CLI command from pyproject.toml configuration.

The `--generate-cli-command` flag reads your pyproject.toml configuration
and outputs the equivalent CLI command. This is useful for debugging
configuration issues or sharing commands with others.

**See also:** [pyproject.toml Configuration](../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --generate-cli-command # (1)!
    ```

    1. :material-arrow-left: `--generate-cli-command` - the option documented here

??? example "Examples"

    **Configuration (pyproject.toml):**

    ```toml
    [tool.datamodel-codegen]
    input = "schema.yaml"
    output = "model.py"
    ```

    **Output:**

    <!-- fmt: off -->

    ```
    datamodel-codegen --input schema.yaml --output model.py
    ```

    <!-- fmt: on -->

---

## `--generate-pyproject-config` {#generate-pyproject-config}

Generate pyproject.toml configuration from CLI arguments.

The `--generate-pyproject-config` flag outputs a pyproject.toml configuration
snippet based on the provided CLI arguments. This is useful for converting
a working CLI command into a reusable configuration file.

**See also:** [pyproject.toml Configuration](../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --generate-pyproject-config --input schema.yaml --output model.py # (1)!
    ```

    1. :material-arrow-left: `--generate-pyproject-config` - the option documented here

??? example "Examples"

    **Output:**

    <!-- fmt: off -->

    ```
    [tool.datamodel-codegen]
    input = "schema.yaml"
    output = "model.py"
    ```

    <!-- fmt: on -->

---

## `--http-headers` {#http-headers}

Fetch a schema from a URL with custom HTTP headers.

The `--url` flag specifies a remote URL to fetch the schema from instead of
a local file. The `--http-headers` flag adds request headers in
`HeaderName:HeaderValue` format.

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --http-headers "Authorization:Bearer token" # (1)!
    ```

    1. :material-arrow-left: `--http-headers` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--http-ignore-tls` {#http-ignore-tls}

Disable TLS certificate verification for HTTPS requests.

The `--http-ignore-tls` flag disables SSL/TLS certificate verification
when fetching schemas from HTTPS URLs. This is useful for development
environments with self-signed certificates. Not recommended for production.

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --http-ignore-tls # (1)!
    ```

    1. :material-arrow-left: `--http-ignore-tls` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--http-local-ref-path` {#http-local-ref-path}

Resolve HTTP references from local schema files.

The `--http-local-ref-path` flag maps HTTP(S) `$ref` URLs to files under
a local schema store instead of fetching them from the network. The host and
URL path are used as the relative path under the schema store. For example,
`https://api.example.com/schemas/pet.json` is read from
`schemas/api.example.com/schemas/pet.json`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --http-local-ref-path schemas # (1)!
    ```

    1. :material-arrow-left: `--http-local-ref-path` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$ref": "https://api.example.com/schemas/pet.json"
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel, RootModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None


    class Model(RootModel[Pet]):
        root: Pet
    ```

    <!-- fmt: on -->

---

## `--http-query-parameters` {#http-query-parameters}

Add query parameters to HTTP requests for remote schemas.

The `--http-query-parameters` flag adds query parameters to HTTP requests
when fetching schemas from URLs. Useful for APIs that require version
or format parameters. Format: `key=value`. Multiple parameters can be
specified: `--http-query-parameters version=v2 format=json`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --http-query-parameters version=v2 format=json # (1)!
    ```

    1. :material-arrow-left: `--http-query-parameters` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--http-timeout` {#http-timeout}

Set timeout for HTTP requests to remote hosts.

The `--http-timeout` flag sets the timeout in seconds for HTTP requests
when fetching schemas from URLs. Useful for slow servers or large schemas.
Default is 30 seconds.

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --http-timeout 60 # (1)!
    ```

    1. :material-arrow-left: `--http-timeout` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--ignore-pyproject` {#ignore-pyproject}

Ignore pyproject.toml configuration file.

The `--ignore-pyproject` flag tells datamodel-codegen to ignore any
[tool.datamodel-codegen] configuration in pyproject.toml. This is useful
when you want to override project defaults with CLI arguments, or when
testing without project configuration.

**See also:** [pyproject.toml Configuration](../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input ignore_pyproject_example.json --ignore-pyproject # (1)!
    ```

    1. :material-arrow-left: `--ignore-pyproject` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "firstName": {"type": "string"},
        "lastName": {"type": "string"}
      }
    }
    ```

    **Output:**

    === "With Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  schema.json

        from __future__ import annotations

        from pydantic import BaseModel


        class Model(BaseModel):
            firstName: str | None = None
            lastName: str | None = None
        ```

        <!-- fmt: on -->

    === "Without Option"

        <!-- fmt: off -->

        ```python
        # generated by datamodel-codegen:
        #   filename:  schema.json

        from __future__ import annotations

        from pydantic import BaseModel, Field


        class Model(BaseModel):
            first_name: str | None = Field(None, alias='firstName')
            last_name: str | None = Field(None, alias='lastName')
        ```

        <!-- fmt: on -->

---

## `--locked` {#locked}

Require an existing remote lock and validate each fetched resource against it (experimental).

`--locked` fails if the selected lock is missing, a resource is unrecorded, or its body differs. It conflicts with
`--update-lock`.

Remote reference lock support is experimental: its lock document schema and request-identity compatibility may evolve. It remains fail-closed on integrity mismatches, and it never persists credentials.

The lock stores opaque SHA-256 request-identity digests and SHA-256 body digests,
never response bodies or request values directly. Each saved display origin contains only the scheme, host, and
explicit port—never a path, query, or request headers. A request identity includes its scheme, host, explicit port,
path, header names, and ordered query parameter names only. If one generation receives different bodies for the same
path and query-name identity, it fails closed rather than sharing a lock entry.

**Related:** [`--http-local-ref-path`](#http-local-ref-path), [`--lockfile`](#lockfile), [`--url`](base-options.md#url)

**Option relationships:**

- **Conflicts:** [`--update-lock`](general-options.md#update-lock)

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --locked --lockfile datamodel-codegen.lock # (1)!
    ```

    1. :material-arrow-left: `--locked` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--lockfile` {#lockfile}

Select the remote reference integrity lock file (experimental).

An existing selected lock is verified automatically; a missing selected lock is ignored unless `--locked` requires it.
Without `--lockfile`, the CLI uses `datamodel-codegen.lock` beside the discovered `pyproject.toml`, or in the invocation
working directory when no project is found. Explicit relative `--lockfile` paths resolve from the invocation working
directory, not the project root or output directory. The public API uses the caller's working directory for both its
default lock and relative `lockfile` paths.

Remote reference lock support is experimental: its lock document schema and request-identity compatibility may evolve. It remains fail-closed on integrity mismatches, and it never persists credentials.

The lock stores opaque SHA-256 request-identity digests and SHA-256 body digests,
never response bodies or request values directly. Each saved display origin contains only the scheme, host, and
explicit port—never a path, query, or request headers. A request identity includes its scheme, host, explicit port,
path, header names, and ordered query parameter names only. If one generation receives different bodies for the same
path and query-name identity, it fails closed rather than sharing a lock entry.

**Related:** [`--http-local-ref-path`](#http-local-ref-path), [`--locked`](#locked), [`--update-lock`](#update-lock), [`--url`](base-options.md#url)

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --update-lock --lockfile datamodel-codegen.lock # (1)!
    ```

    1. :material-arrow-left: `--lockfile` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--module-split-mode` {#module-split-mode}

Split generated models into separate files, one per model class.

The `--module-split-mode=single` flag generates each model class in its own file,
named after the class in snake_case. Use with `--all-exports-scope=recursive` to
create an __init__.py that re-exports all models for convenient imports.

**Related:** [`--all-exports-scope`](#all-exports-scope), [`--use-exact-imports`](template-customization.md#use-exact-imports)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input input.json --module-split-mode single --all-exports-scope recursive --use-exact-imports # (1)!
    ```

    1. :material-arrow-left: `--module-split-mode` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "User": {
          "type": "object",
          "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"}
          }
        },
        "Order": {
          "type": "object",
          "properties": {
            "id": {"type": "integer"},
            "user": {"$ref": "#/definitions/User"}
          }
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # __init__.py
    # generated by datamodel-codegen:
    #   filename:  input.json

    from __future__ import annotations

    from .model import Model
    from .order import Order
    from .user import User

    __all__ = [
        "Model",
        "Order",
        "User",
    ]

    # model.py
    # generated by datamodel-codegen:
    #   filename:  input.json

    from __future__ import annotations

    from typing import Any

    from pydantic import RootModel


    class Model(RootModel[Any]):
        root: Any

    # order.py
    # generated by datamodel-codegen:
    #   filename:  input.json

    from __future__ import annotations

    from pydantic import BaseModel

    from .user import User


    class Order(BaseModel):
        id: int | None = None
        user: User | None = None

    # user.py
    # generated by datamodel-codegen:
    #   filename:  input.json

    from __future__ import annotations

    from pydantic import BaseModel


    class User(BaseModel):
        id: int | None = None
        name: str | None = None
    ```

    <!-- fmt: on -->

---

## `--shared-module-name` {#shared-module-name}

Customize the name of the shared module for deduplicated models.

The `--shared-module-name` flag sets the name of the shared module created
when using `--reuse-model` with `--reuse-scope=tree`. This module contains
deduplicated models that are referenced from multiple files. Default is
`shared`. Use this if your schema already has a file named `shared`.

Note: This option only affects modular output with tree-level model reuse.

**See also:** [Model Reuse and Deduplication](../model-reuse.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input pet_simple.json --shared-module-name my_shared # (1)!
    ```

    1. :material-arrow-left: `--shared-module-name` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  pet_simple.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--strict-refs` {#strict-refs}

Treat unresolved local `$ref` JSON pointers as errors.

By default, an unresolved local pointer emits a warning and retains the generated
fallback `Any` model. Enable this option in validation-sensitive workflows to stop
generation instead. Existing empty schemas remain valid references.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input empty_local_ref.json --strict-refs # (1)!
    ```

    1. :material-arrow-left: `--strict-refs` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$defs": {
        "Empty": {}
      },
      "$ref": "#/$defs/Empty"
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  empty_local_ref.json

    from __future__ import annotations

    from typing import Any

    from pydantic import RootModel


    class Empty(RootModel[Any]):
        root: Any


    class Model(RootModel[Empty]):
        root: Empty
    ```

    <!-- fmt: on -->

---

## `--update-lock` {#update-lock}

Create or atomically update the selected remote lock after generation (experimental).

`--update-lock` creates or refreshes the selected `--lockfile` from every remote resource reached during this run.
It conflicts with `--locked`.

Remote reference lock support is experimental: its lock document schema and request-identity compatibility may evolve. It remains fail-closed on integrity mismatches, and it never persists credentials.

The lock stores opaque SHA-256 request-identity digests and SHA-256 body digests,
never response bodies or request values directly. Each saved display origin contains only the scheme, host, and
explicit port—never a path, query, or request headers. A request identity includes its scheme, host, explicit port,
path, header names, and ordered query parameter names only. If one generation receives different bodies for the same
path and query-name identity, it fails closed rather than sharing a lock entry.

**Related:** [`--http-local-ref-path`](#http-local-ref-path), [`--lockfile`](#lockfile), [`--url`](base-options.md#url)

**Option relationships:**

- **Conflicts:** [`--locked`](general-options.md#locked)

!!! tip "Usage"

    ```bash
    datamodel-codegen --url https://api.example.com/schema.json --update-lock --lockfile datamodel-codegen.lock # (1)!
    ```

    1. :material-arrow-left: `--update-lock` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Pet",
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  https://api.example.com/schema.json
    #   timestamp: 2019-07-26T00:00:00+00:00

    from __future__ import annotations

    from pydantic import BaseModel


    class Pet(BaseModel):
        id: int | None = None
        name: str | None = None
        tag: str | None = None
    ```

    <!-- fmt: on -->

---

## `--watch` {#watch}

Watch input file(s) for changes and regenerate output automatically.

The `--watch` flag enables continuous file monitoring mode. When enabled,
datamodel-codegen watches the input file or directory for changes and
automatically regenerates the output whenever changes are detected.
Press Ctrl+C to stop watching.

**See also:** [pyproject.toml Configuration](../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --watch --check # (1)!
    ```

    1. :material-arrow-left: `--watch` - the option documented here

!!! warning "Requires extra dependency"

    The watch feature requires the `watch` extra:

    ```bash
    pip install 'datamodel-code-generator[watch]'
    ```

??? example "Examples"

    === "JSON Schema"

        **Input Schema:**

        ```json
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "title": "Person",
          "type": "object",
          "properties": {
            "firstName": {
              "type": "string",
              "description": "The person's first name."
            },
            "lastName": {
              "type": ["string", "null"],
              "description": "The person's last name."
            },
            "age": {
              "description": "Age in years which must be equal to or greater than zero.",
              "type": "integer",
              "minimum": 0
            },
            "friends": {
              "type": "array"
            },
            "comment": {
              "type": "null"
            }
          }
        }
        ```

        **Output:**

        <!-- fmt: off -->

        ```
        Error: --watch and --check cannot be used together
        ```

        <!-- fmt: on -->

    === "unknown"

        **Output:**

        <!-- fmt: off -->

        ```
        Error: --watch requires --input file path
        ```

        <!-- fmt: on -->

---

## `--watch-delay` {#watch-delay}

Set debounce delay in seconds for watch mode.

The `--watch-delay` option configures the debounce interval (default: 0.5 seconds)
for watch mode. This prevents multiple regenerations when files are rapidly
modified in succession. The delay ensures that after the last file change,
the generator waits the specified time before regenerating.

**Related:** [`--watch`](general-options.md#watch)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input person.json --watch --watch-delay 1.5 # (1)!
    ```

    1. :material-arrow-left: `--watch-delay` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```json
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Person",
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string",
          "description": "The person's first name."
        },
        "lastName": {
          "type": ["string", "null"],
          "description": "The person's last name."
        },
        "age": {
          "description": "Age in years which must be equal to or greater than zero.",
          "type": "integer",
          "minimum": 0
        },
        "friends": {
          "type": "array"
        },
        "comment": {
          "type": "null"
        }
      }
    }
    ```

    **Output:**

    <!-- fmt: off -->

    ```
    Watching
    ```

    <!-- fmt: on -->

---

---

# Target Generation Options

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/target-generation-options/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--client-body-arguments`](#client-body-arguments) | Choose how operation methods take request bodies (experiment... |
| [`--client-default-base-url`](#client-default-base-url) | Set the server URL of operations that declare no servers (ex... |
| [`--client-model-package`](#client-model-package) | Name the import path of the models the client package import... |
| [`--client-operations`](#client-operations) | Set the client settings of single operations (experimental). |
| [`--client-output`](#client-output) | Write the client package to this directory (experimental). |
| [`--client-package`](#client-package) | Name the import path of the client package (experimental). |
| [`--client-protocols`](#client-protocols) | Declare the protocol helpers of the client package (experime... |
| [`--client-resource-names`](#client-resource-names) | Name the resources of tags (experimental). |
| [`--client-server-base-url`](#client-server-base-url) | Resolve relative server URLs against this base URL (experime... |
| [`--client-signature-style`](#client-signature-style) | Declare the arguments of the operation methods (experimental... |
| [`--generate-client`](#generate-client) | Generate an HTTPX2 client package for the models (experiment... |
| [`--generate-server`](#generate-server) | Generate a FastAPI server package for the models (experiment... |
| [`--server-body-mode`](#server-body-mode) | Choose how service methods receive request bodies (experimen... |
| [`--server-body-modes`](#server-body-modes) | Set the body mode of single operations (experimental). |
| [`--server-handler-mode`](#server-handler-mode) | Declare the service methods as plain or coroutine functions ... |
| [`--server-handler-modes`](#server-handler-modes) | Set the handler mode of single operations (experimental). |
| [`--server-include-request`](#server-include-request) | Pass the Starlette Request to every service method (experime... |
| [`--server-layout`](#server-layout) | Choose how the server package lays out its routes (experimen... |
| [`--server-model-package`](#server-model-package) | Name the import path of the models the server package import... |
| [`--server-operation-names`](#server-operation-names) | Name the service methods of single operations (experimental)... |
| [`--server-output`](#server-output) | Write the server package to this directory (experimental). |
| [`--server-package`](#server-package) | Name the import path of the server package (experimental). |
| [`--server-parameter-names`](#server-parameter-names) | Name the method arguments of single operations (experimental... |
| [`--server-primary-responses`](#server-primary-responses) | Choose the response a bare return value of an operation take... |
| [`--server-router-names`](#server-router-names) | Name router groups (experimental). |

---

## `--client-body-arguments` {#client-body-arguments}

Choose how operation methods take request bodies (experimental).

`body` (the default) takes the body as one `body` argument; `both` also takes the properties of an object body as
keyword arguments, so a call can pass either. The `body_arguments` of an operation in `--client-operations`
overrides it for that operation.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-body-arguments` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models --client-body-arguments both # (1)!
    ```

    1. :material-arrow-left: `--client-body-arguments` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous operations of the pets resource."""

    from __future__ import annotations

    from contextlib import AbstractContextManager
    from functools import cached_property
    from typing import Literal, overload

    import models

    from ... import _operations
    from ..._runtime.client.client import ClientCore
    from ...options import UNSET, RequestOptions
    from ...responses import RawResponse, Response
    from ...types.pets import CreatePetResponse, ListPetsResponse


    class PetsResource:
        """The pets operations."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        @cached_property
        def with_response(self) -> PetsWithResponse:
            """The same operations, returning each result with its response metadata."""
            return PetsWithResponse(self._core)

        @cached_property
        def with_raw_response(self) -> PetsWithRawResponse:
            """The same operations, returning each raw response with its body read into memory."""
            return PetsWithRawResponse(self._core)

        @cached_property
        def with_streaming_response(self) -> PetsWithStreamingResponse:
            """The same operations, returning blocks that send each call on entry and stream its response."""
            return PetsWithStreamingResponse(self._core)

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> ListPetsResponse:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            ).data

        @overload
        def create_pet(
            self,
            *,
            body: models.NewPet,
            name: UNSET = UNSET,
            tag: UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse: ...
        @overload
        def create_pet(
            self,
            *,
            body: UNSET = UNSET,
            name: str,
            tag: str | UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse: ...
        def create_pet(
            self,
            *,
            body: models.NewPet | UNSET = UNSET,
            name: str | UNSET = UNSET,
            tag: str | UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                fields=(name, tag),
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            ).data


    class PetsWithResponse:
        """The pets operations, returning each result with its response metadata."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[ListPetsResponse]:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        @overload
        def create_pet(
            self,
            *,
            body: models.NewPet,
            name: UNSET = UNSET,
            tag: UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]: ...
        @overload
        def create_pet(
            self,
            *,
            body: UNSET = UNSET,
            name: str,
            tag: str | UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]: ...
        def create_pet(
            self,
            *,
            body: models.NewPet | UNSET = UNSET,
            name: str | UNSET = UNSET,
            tag: str | UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                fields=(name, tag),
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithRawResponse:
        """The pets operations, returning each raw response with its body read into memory."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call GET /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        @overload
        def create_pet(
            self,
            *,
            body: models.NewPet,
            name: UNSET = UNSET,
            tag: UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse: ...
        @overload
        def create_pet(
            self,
            *,
            body: UNSET = UNSET,
            name: str,
            tag: str | UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse: ...
        def create_pet(
            self,
            *,
            body: models.NewPet | UNSET = UNSET,
            name: str | UNSET = UNSET,
            tag: str | UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call POST /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_1,
                (),
                body=body,
                fields=(name, tag),
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithStreamingResponse:
        """The pets operations, returning blocks that send each call on entry and stream its response."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call GET /pets.
            """
            return self._core.stream(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        @overload
        def create_pet(
            self,
            *,
            body: models.NewPet,
            name: UNSET = UNSET,
            tag: UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]: ...
        @overload
        def create_pet(
            self,
            *,
            body: UNSET = UNSET,
            name: str,
            tag: str | UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]: ...
        def create_pet(
            self,
            *,
            body: models.NewPet | UNSET = UNSET,
            name: str | UNSET = UNSET,
            tag: str | UNSET = UNSET,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call POST /pets.
            """
            return self._core.stream(
                _operations.OPERATION_1,
                (),
                body=body,
                fields=(name, tag),
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )
    ```

    <!-- fmt: on -->

---

## `--client-default-base-url` {#client-default-base-url}

Set the server URL of operations that declare no servers (experimental).

An absolute `http` or `https` URL without userinfo, query, or fragment. Operations whose document and path declare
servers keep them.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-default-base-url` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options-unserved.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models --client-default-base-url https://api.example.com/v1 # (1)!
    ```

    1. :material-arrow-left: `--client-default-base-url` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options-unserved.yaml

    """The operation registry of this package; regenerate it instead of editing."""

    from __future__ import annotations

    from typing import Final

    from ._generated import model_bindings
    from ._runtime.client.operations import (
        BodyMedia,
        OperationPlan,
        ParameterSpec,
        RequestBody,
        ResponseDecoder,
        ServerPlan,
        model_branch,
    )
    from ._runtime.model_codecs.parameters import ParameterPlan
    from .types.pets import CreatePetResponse, ListPetsResponse

    _SERVERS_0: Final = (ServerPlan(url='https://api.example.com/v1'),)

    OPERATION_0: Final[OperationPlan[ListPetsResponse]] = OperationPlan(
        operation_id='listPets',
        method='GET',
        path='/pets',
        servers=_SERVERS_0,
        responses=ResponseDecoder((model_branch('200', 'application/json', 'json', model_bindings.codec_2),), ()),
        parameters=(ParameterSpec(plan=ParameterPlan(location='query', name='limit', style='form', explode=True, kind='integer', reserved_names=('cursor',)), codec=model_bindings.codec_0), ParameterSpec(plan=ParameterPlan(location='query', name='cursor', style='form', explode=True, reserved_names=('limit',)), codec=model_bindings.codec_1)),
    )

    OPERATION_1: Final[OperationPlan[CreatePetResponse]] = OperationPlan(
        operation_id='createPet',
        method='POST',
        path='/pets',
        servers=_SERVERS_0,
        responses=ResponseDecoder((model_branch('201', 'application/json', 'json', model_bindings.codec_4),), ()),
        body=RequestBody(media=(BodyMedia(media_type='application/json', kind='json', codec=model_bindings.codec_3),), default='application/json', required=True),
    )
    ```

    <!-- fmt: on -->

---

## `--client-model-package` {#client-model-package}

Name the import path of the models the client package imports (experimental).

`--client-model-package` is required with `--generate-client`, and names the module or package `--output`
generates.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-model-package` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models # (1)!
    ```

    1. :material-arrow-left: `--client-model-package` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous operations of the pets resource."""

    from __future__ import annotations

    from contextlib import AbstractContextManager
    from functools import cached_property
    from typing import Literal

    import models

    from ... import _operations
    from ..._runtime.client.client import ClientCore
    from ...options import UNSET, RequestOptions
    from ...responses import RawResponse, Response
    from ...types.pets import CreatePetResponse, ListPetsResponse


    class PetsResource:
        """The pets operations."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        @cached_property
        def with_response(self) -> PetsWithResponse:
            """The same operations, returning each result with its response metadata."""
            return PetsWithResponse(self._core)

        @cached_property
        def with_raw_response(self) -> PetsWithRawResponse:
            """The same operations, returning each raw response with its body read into memory."""
            return PetsWithRawResponse(self._core)

        @cached_property
        def with_streaming_response(self) -> PetsWithStreamingResponse:
            """The same operations, returning blocks that send each call on entry and stream its response."""
            return PetsWithStreamingResponse(self._core)

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> ListPetsResponse:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            ).data

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            ).data


    class PetsWithResponse:
        """The pets operations, returning each result with its response metadata."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[ListPetsResponse]:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithRawResponse:
        """The pets operations, returning each raw response with its body read into memory."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call GET /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call POST /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithStreamingResponse:
        """The pets operations, returning blocks that send each call on entry and stream its response."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call GET /pets.
            """
            return self._core.stream(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call POST /pets.
            """
            return self._core.stream(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )
    ```

    <!-- fmt: on -->

---

## `--client-operations` {#client-operations}

Set the client settings of single operations (experimental).

The JSON object, inline or in a file, maps operation references to their settings. An operation reference is the
JSON pointer of the path item method, such as `/paths/~1pets/get`, optionally after a document and `#`, such as
`pets.yaml#/paths/~1pets/get`. A relative document resolves against the JSON file that holds the reference, or
without a file against the working directory, and against the pyproject.toml directory for a table. The settings are
`resource`, `name`, `parameter_names` (keyed by location and name,
such as `{"query:limit": "page_size"}`), `request_media_type`, `response_media_type`, `description`,
`body_arguments`, which overrides `--client-body-arguments`, `body_field_names` (keyed by media type, then property,
such as `{"application/json": {"petName": "pet_name"}}`), and `runtime`: `request_id_header`, `success_statuses`,
`retry_safety`, `idempotency` (`{"header_name": "Idempotency-Key"}`), `retry_after_ms_header`,
`should_retry_header`, `auth_challenge_less_401`, and `accepted_content_encodings`. In pyproject.toml,
`client-operations` is a table, and a command-line value replaces the whole table.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-operations` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models --client-operations '{"/paths/~1pets/get": {"name": "list_all", "parameter_names": {"query:limit": "page_size"}}}' # (1)!
    ```

    1. :material-arrow-left: `--client-operations` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous operations of the pets resource."""

    from __future__ import annotations

    from contextlib import AbstractContextManager
    from functools import cached_property
    from typing import Literal

    import models

    from ... import _operations
    from ..._runtime.client.client import ClientCore
    from ...options import UNSET, RequestOptions
    from ...responses import RawResponse, Response
    from ...types.pets import CreatePetResponse, ListAllResponse


    class PetsResource:
        """The pets operations."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        @cached_property
        def with_response(self) -> PetsWithResponse:
            """The same operations, returning each result with its response metadata."""
            return PetsWithResponse(self._core)

        @cached_property
        def with_raw_response(self) -> PetsWithRawResponse:
            """The same operations, returning each raw response with its body read into memory."""
            return PetsWithRawResponse(self._core)

        @cached_property
        def with_streaming_response(self) -> PetsWithStreamingResponse:
            """The same operations, returning blocks that send each call on entry and stream its response."""
            return PetsWithStreamingResponse(self._core)

        def list_all(
            self,
            *,
            page_size: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> ListAllResponse:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (page_size, cursor),
                options=options,
                response_media_type=response_media_type,
            ).data

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            ).data


    class PetsWithResponse:
        """The pets operations, returning each result with its response metadata."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_all(
            self,
            *,
            page_size: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[ListAllResponse]:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (page_size, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithRawResponse:
        """The pets operations, returning each raw response with its body read into memory."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_all(
            self,
            *,
            page_size: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call GET /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_0,
                (page_size, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call POST /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithStreamingResponse:
        """The pets operations, returning blocks that send each call on entry and stream its response."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_all(
            self,
            *,
            page_size: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call GET /pets.
            """
            return self._core.stream(
                _operations.OPERATION_0,
                (page_size, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call POST /pets.
            """
            return self._core.stream(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )
    ```

    <!-- fmt: on -->

---

## `--client-output` {#client-output}

Write the client package to this directory (experimental).

`--client-output` is required with `--generate-client`. A path given on the command line is relative to the working
directory, and the `client-output` key of pyproject.toml is relative to the pyproject.toml directory, as for
`--output`.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-output` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models # (1)!
    ```

    1. :material-arrow-left: `--client-output` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous operations of the pets resource."""

    from __future__ import annotations

    from contextlib import AbstractContextManager
    from functools import cached_property
    from typing import Literal

    import models

    from ... import _operations
    from ..._runtime.client.client import ClientCore
    from ...options import UNSET, RequestOptions
    from ...responses import RawResponse, Response
    from ...types.pets import CreatePetResponse, ListPetsResponse


    class PetsResource:
        """The pets operations."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        @cached_property
        def with_response(self) -> PetsWithResponse:
            """The same operations, returning each result with its response metadata."""
            return PetsWithResponse(self._core)

        @cached_property
        def with_raw_response(self) -> PetsWithRawResponse:
            """The same operations, returning each raw response with its body read into memory."""
            return PetsWithRawResponse(self._core)

        @cached_property
        def with_streaming_response(self) -> PetsWithStreamingResponse:
            """The same operations, returning blocks that send each call on entry and stream its response."""
            return PetsWithStreamingResponse(self._core)

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> ListPetsResponse:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            ).data

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            ).data


    class PetsWithResponse:
        """The pets operations, returning each result with its response metadata."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[ListPetsResponse]:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithRawResponse:
        """The pets operations, returning each raw response with its body read into memory."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call GET /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call POST /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithStreamingResponse:
        """The pets operations, returning blocks that send each call on entry and stream its response."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call GET /pets.
            """
            return self._core.stream(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call POST /pets.
            """
            return self._core.stream(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )
    ```

    <!-- fmt: on -->

---

## `--client-package` {#client-package}

Name the import path of the client package (experimental).

`--client-package` is required with `--generate-client`. The generated README and the dependency command a
generation prints name the package by it; the package imports its own modules relatively.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-package` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models # (1)!
    ```

    1. :material-arrow-left: `--client-package` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous operations of the pets resource."""

    from __future__ import annotations

    from contextlib import AbstractContextManager
    from functools import cached_property
    from typing import Literal

    import models

    from ... import _operations
    from ..._runtime.client.client import ClientCore
    from ...options import UNSET, RequestOptions
    from ...responses import RawResponse, Response
    from ...types.pets import CreatePetResponse, ListPetsResponse


    class PetsResource:
        """The pets operations."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        @cached_property
        def with_response(self) -> PetsWithResponse:
            """The same operations, returning each result with its response metadata."""
            return PetsWithResponse(self._core)

        @cached_property
        def with_raw_response(self) -> PetsWithRawResponse:
            """The same operations, returning each raw response with its body read into memory."""
            return PetsWithRawResponse(self._core)

        @cached_property
        def with_streaming_response(self) -> PetsWithStreamingResponse:
            """The same operations, returning blocks that send each call on entry and stream its response."""
            return PetsWithStreamingResponse(self._core)

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> ListPetsResponse:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            ).data

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            ).data


    class PetsWithResponse:
        """The pets operations, returning each result with its response metadata."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[ListPetsResponse]:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithRawResponse:
        """The pets operations, returning each raw response with its body read into memory."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call GET /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call POST /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithStreamingResponse:
        """The pets operations, returning blocks that send each call on entry and stream its response."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call GET /pets.
            """
            return self._core.stream(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call POST /pets.
            """
            return self._core.stream(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )
    ```

    <!-- fmt: on -->

---

## `--client-protocols` {#client-protocols}

Declare the protocol helpers of the client package (experimental).

The JSON object, inline or in a file, maps each helper's name to the definition of a pagination, polling, stream,
WebSocket, cache, upload, or webhook helper, as the Python client guide describes. Relative documents that its
references name resolve against the directory of the JSON file that holds them, on the command line and for the
`client-protocols` key alike. For inline JSON they resolve against the working directory, and for a table of the
`client-protocols` key against the pyproject.toml directory.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-protocols` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models --client-protocols protocols.json # (1)!
    ```

    1. :material-arrow-left: `--client-protocols` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous protocol helpers of this package, by their dotted names."""

    from __future__ import annotations

    from functools import cached_property

    import models

    from .._runtime.client.client import ClientCore as ClientCore_1
    from .._runtime.model_codecs.media import JSONValue
    from .._runtime.protocols.client import ClientCore
    from .._runtime.protocols.pagination import (
        Page,
        Pager,
        first_page,
        following_page,
        iterate_pages,
        resume_pages,
    )
    from ..options import UNSET, RequestOptions
    from ..types.pets import ListPetsResponse
    from . import PaginationOptions, _plans


    class ProtocolHelpers:
        """The protocol helpers of this API."""

        def __init__(self, core: ClientCore_1) -> None:
            """Keep the client core its helpers send through."""
            self._core = ClientCore.from_client(core)

        @cached_property
        def pets(self) -> PetsProtocols:
            """The pets protocol helpers."""
            return PetsProtocols(self._core)


    class PetsProtocols:
        """The pets protocol helpers."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core its helpers send through."""
            self._core = core

        @cached_property
        def all(self) -> PetsAllPagination:
            """The pets.all pagination helper."""
            return PetsAllPagination(self._core)


    class PetsAllPagination:
        """The pets.all pagination helper of GET /pets."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the helper sends through."""
            self._core = core

        def page(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            pagination_options: PaginationOptions | None = None,
            options: RequestOptions | None = None,
        ) -> Page[models.Pet, ListPetsResponse]:
            """Fetch the first page of GET /pets."""
            return first_page(
                self._core,
                _plans.PLAN_0,
                (limit, cursor),
                pagination_options=pagination_options,
                options=options,
            )

        def iterate(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            pagination_options: PaginationOptions | None = None,
            options: RequestOptions | None = None,
        ) -> Pager[models.Pet, ListPetsResponse]:
            """Return a pager over the items of GET /pets; it sends nothing until it is iterated."""
            return iterate_pages(
                self._core,
                _plans.PLAN_0,
                (limit, cursor),
                pagination_options=pagination_options,
                options=options,
            )

        def next_page(
            self,
            page: Page[models.Pet, ListPetsResponse],
            *,
            pagination_options: PaginationOptions | None = None,
            options: RequestOptions | None = None,
        ) -> Page[models.Pet, ListPetsResponse] | None:
            """Fetch the page after a page of this helper, or return None after the last page."""
            return following_page(
                self._core,
                _plans.PLAN_0,
                page,
                pagination_options=pagination_options,
                options=options,
            )

        def resume(
            self,
            state: JSONValue,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            pagination_options: PaginationOptions | None = None,
            options: RequestOptions | None = None,
        ) -> Pager[models.Pet, ListPetsResponse]:
            """Return a pager continuing a checkpoint; it sends nothing until it is iterated."""
            return resume_pages(
                self._core,
                _plans.PLAN_0,
                state,
                (limit, cursor),
                pagination_options=pagination_options,
                options=options,
            )
    ```

    <!-- fmt: on -->

---

## `--client-resource-names` {#client-resource-names}

Name the resources of tags (experimental).

The JSON object, inline or in a file, maps a tag to the dotted namespace of the resource its operations join, such
as `{"pets": "store.pets"}` for `client.store.pets`. Other operations join the resource of their first tag, and
operations without a tag join the resource `default`. In
pyproject.toml, `client-resource-names` is a table, and a command-line value replaces the whole table.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-resource-names` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models --client-resource-names '{"pets": "animals"}' # (1)!
    ```

    1. :material-arrow-left: `--client-resource-names` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous operations of the animals resource."""

    from __future__ import annotations

    from contextlib import AbstractContextManager
    from functools import cached_property
    from typing import Literal

    import models

    from ... import _operations
    from ..._runtime.client.client import ClientCore
    from ...options import UNSET, RequestOptions
    from ...responses import RawResponse, Response
    from ...types.animals import CreatePetResponse, ListPetsResponse


    class AnimalsResource:
        """The animals operations."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        @cached_property
        def with_response(self) -> AnimalsWithResponse:
            """The same operations, returning each result with its response metadata."""
            return AnimalsWithResponse(self._core)

        @cached_property
        def with_raw_response(self) -> AnimalsWithRawResponse:
            """The same operations, returning each raw response with its body read into memory."""
            return AnimalsWithRawResponse(self._core)

        @cached_property
        def with_streaming_response(self) -> AnimalsWithStreamingResponse:
            """The same operations, returning blocks that send each call on entry and stream its response."""
            return AnimalsWithStreamingResponse(self._core)

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> ListPetsResponse:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            ).data

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            ).data


    class AnimalsWithResponse:
        """The animals operations, returning each result with its response metadata."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[ListPetsResponse]:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class AnimalsWithRawResponse:
        """The animals operations, returning each raw response with its body read into memory."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call GET /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call POST /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class AnimalsWithStreamingResponse:
        """The animals operations, returning blocks that send each call on entry and stream its response."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call GET /pets.
            """
            return self._core.stream(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call POST /pets.
            """
            return self._core.stream(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )
    ```

    <!-- fmt: on -->

---

## `--client-server-base-url` {#client-server-base-url}

Resolve relative server URLs against this base URL (experimental).

An absolute `http` or `https` URL without userinfo, query, or fragment. Without it, relative server URLs resolve
against the document's URL when it is read from one.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-server-base-url` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options-relative.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models --client-server-base-url https://api.example.com/ # (1)!
    ```

    1. :material-arrow-left: `--client-server-base-url` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: /v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options-relative.yaml

    """The operation registry of this package; regenerate it instead of editing."""

    from __future__ import annotations

    from typing import Final

    from ._generated import model_bindings
    from ._runtime.client.operations import (
        BodyMedia,
        OperationPlan,
        ParameterSpec,
        RequestBody,
        ResponseDecoder,
        ServerPlan,
        model_branch,
    )
    from ._runtime.model_codecs.parameters import ParameterPlan
    from .types.pets import CreatePetResponse, ListPetsResponse

    _SERVERS_0: Final = (ServerPlan(url='https://api.example.com/v1'),)

    OPERATION_0: Final[OperationPlan[ListPetsResponse]] = OperationPlan(
        operation_id='listPets',
        method='GET',
        path='/pets',
        servers=_SERVERS_0,
        responses=ResponseDecoder((model_branch('200', 'application/json', 'json', model_bindings.codec_2),), ()),
        parameters=(ParameterSpec(plan=ParameterPlan(location='query', name='limit', style='form', explode=True, kind='integer', reserved_names=('cursor',)), codec=model_bindings.codec_0), ParameterSpec(plan=ParameterPlan(location='query', name='cursor', style='form', explode=True, reserved_names=('limit',)), codec=model_bindings.codec_1)),
    )

    OPERATION_1: Final[OperationPlan[CreatePetResponse]] = OperationPlan(
        operation_id='createPet',
        method='POST',
        path='/pets',
        servers=_SERVERS_0,
        responses=ResponseDecoder((model_branch('201', 'application/json', 'json', model_bindings.codec_4),), ()),
        body=RequestBody(media=(BodyMedia(media_type='application/json', kind='json', codec=model_bindings.codec_3),), default='application/json', required=True),
    )
    ```

    <!-- fmt: on -->

---

## `--client-signature-style` {#client-signature-style}

Declare the arguments of the operation methods (experimental).

`explicit` (the default) declares each argument as a keyword parameter; `unpack` declares
`**kwargs: Unpack[TypedDict]` with one TypedDict per overload of each operation, whose keys are the same arguments.

**Option relationships:**

- **Requires:** [`--generate-client`](target-generation-options.md#generate-client) - `--client-signature-style` requires `--generate-client httpx2`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models --client-signature-style unpack # (1)!
    ```

    1. :material-arrow-left: `--client-signature-style` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous operations of the pets resource."""

    from __future__ import annotations

    from contextlib import AbstractContextManager
    from functools import cached_property

    from typing_extensions import Unpack

    from ... import _operations
    from ..._generated.client_arguments import (
        KEYWORDS_0,
        KEYWORDS_1,
        Operation0Arguments,
        Operation1Arguments,
    )
    from ..._runtime.client.client import ClientCore
    from ...options import UNSET
    from ...responses import RawResponse, Response
    from ...types.pets import CreatePetResponse, ListPetsResponse


    class PetsResource:
        """The pets operations."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        @cached_property
        def with_response(self) -> PetsWithResponse:
            """The same operations, returning each result with its response metadata."""
            return PetsWithResponse(self._core)

        @cached_property
        def with_raw_response(self) -> PetsWithRawResponse:
            """The same operations, returning each raw response with its body read into memory."""
            return PetsWithRawResponse(self._core)

        @cached_property
        def with_streaming_response(self) -> PetsWithStreamingResponse:
            """The same operations, returning blocks that send each call on entry and stream its response."""
            return PetsWithStreamingResponse(self._core)

        def list_pets(
            self,
            **kwargs: Unpack[Operation0Arguments],
        ) -> ListPetsResponse:
            """
            Call GET /pets.
            """
            KEYWORDS_0.check(kwargs)
            return self._core.execute(
                _operations.OPERATION_0,
                (kwargs.get('limit', UNSET), kwargs.get('cursor', UNSET)),
                options=kwargs.get('options'),
                response_media_type=kwargs.get('response_media_type'),
            ).data

        def create_pet(
            self,
            **kwargs: Unpack[Operation1Arguments],
        ) -> CreatePetResponse:
            """
            Call POST /pets.
            """
            KEYWORDS_1.check(kwargs)
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=kwargs['body'],
                media_type=kwargs.get('media_type'),
                options=kwargs.get('options'),
                response_media_type=kwargs.get('response_media_type'),
            ).data


    class PetsWithResponse:
        """The pets operations, returning each result with its response metadata."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            **kwargs: Unpack[Operation0Arguments],
        ) -> Response[ListPetsResponse]:
            """
            Call GET /pets.
            """
            KEYWORDS_0.check(kwargs)
            return self._core.execute(
                _operations.OPERATION_0,
                (kwargs.get('limit', UNSET), kwargs.get('cursor', UNSET)),
                options=kwargs.get('options'),
                response_media_type=kwargs.get('response_media_type'),
            )

        def create_pet(
            self,
            **kwargs: Unpack[Operation1Arguments],
        ) -> Response[CreatePetResponse]:
            """
            Call POST /pets.
            """
            KEYWORDS_1.check(kwargs)
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=kwargs['body'],
                media_type=kwargs.get('media_type'),
                options=kwargs.get('options'),
                response_media_type=kwargs.get('response_media_type'),
            )


    class PetsWithRawResponse:
        """The pets operations, returning each raw response with its body read into memory."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            **kwargs: Unpack[Operation0Arguments],
        ) -> RawResponse:
            """
            Call GET /pets.
            """
            KEYWORDS_0.check(kwargs)
            return self._core.execute_raw(
                _operations.OPERATION_0,
                (kwargs.get('limit', UNSET), kwargs.get('cursor', UNSET)),
                options=kwargs.get('options'),
                response_media_type=kwargs.get('response_media_type'),
            )

        def create_pet(
            self,
            **kwargs: Unpack[Operation1Arguments],
        ) -> RawResponse:
            """
            Call POST /pets.
            """
            KEYWORDS_1.check(kwargs)
            return self._core.execute_raw(
                _operations.OPERATION_1,
                (),
                body=kwargs['body'],
                media_type=kwargs.get('media_type'),
                options=kwargs.get('options'),
                response_media_type=kwargs.get('response_media_type'),
            )


    class PetsWithStreamingResponse:
        """The pets operations, returning blocks that send each call on entry and stream its response."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            **kwargs: Unpack[Operation0Arguments],
        ) -> AbstractContextManager[RawResponse]:
            """
            Call GET /pets.
            """
            KEYWORDS_0.check(kwargs)
            return self._core.stream(
                _operations.OPERATION_0,
                (kwargs.get('limit', UNSET), kwargs.get('cursor', UNSET)),
                options=kwargs.get('options'),
                response_media_type=kwargs.get('response_media_type'),
            )

        def create_pet(
            self,
            **kwargs: Unpack[Operation1Arguments],
        ) -> AbstractContextManager[RawResponse]:
            """
            Call POST /pets.
            """
            KEYWORDS_1.check(kwargs)
            return self._core.stream(
                _operations.OPERATION_1,
                (),
                body=kwargs['body'],
                media_type=kwargs.get('media_type'),
                options=kwargs.get('options'),
                response_media_type=kwargs.get('response_media_type'),
            )
    ```

    <!-- fmt: on -->

---

## `--generate-client` {#generate-client}

Generate an HTTPX2 client package for the models (experimental).

`--generate-client httpx2` generates the models of an OpenAPI document as usual and, in the same run, an HTTPX2
client package at `--client-output`: a `Client` and an `AsyncClient` with a resource for each tag and a method for
each operation. The models need the `api` scope (`--openapi-scopes schemas api`) and a target Python version of 3.11
or later. Like every client setting, it can also be set in `[tool.datamodel-codegen]` of pyproject.toml, here as
`generate-client = "httpx2"`. It cannot be used with `--generate-server`.

**Option relationships:**

- **Requires:** [`--client-output`](target-generation-options.md#client-output) - `--generate-client` requires `--client-output`.
- **Requires:** [`--client-package`](target-generation-options.md#client-package) - `--generate-client` requires `--client-package`.
- **Requires:** [`--client-model-package`](target-generation-options.md#client-model-package) - `--generate-client` requires `--client-model-package`.
- **Requires:** [`--input-file-type`](base-options.md#input-file-type) = `openapi` - `--generate-client` requires `--input-file-type openapi`.
- **Conflicts:** [`--generate-server`](target-generation-options.md#generate-server) - `--generate-client` can not be used with `--generate-server`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-client httpx2 --client-output client --client-package client --client-model-package models # (1)!
    ```

    1. :material-arrow-left: `--generate-client` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info:
      title: Pets
      version: 1.0.0
    servers:
      - url: https://api.example.com/v1
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          summary: List the pets.
          parameters:
            - name: limit
              in: query
              schema: {type: integer}
            - name: cursor
              in: query
              schema: {type: string}
          responses:
            '200':
              description: A page of pets.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pets'}
        post:
          operationId: createPet
          tags: [pets]
          summary: Create a pet.
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: '#/components/schemas/NewPet'}
          responses:
            '201':
              description: The created pet.
              content:
                application/json:
                  schema: {$ref: '#/components/schemas/Pet'}
    components:
      schemas:
        NewPet:
          type: object
          required: [name]
          properties:
            name: {type: string}
            tag: {type: string}
        Pet:
          type: object
          required: [id, name]
          properties:
            id: {type: integer}
            name: {type: string}
            tag: {type: string}
        Pets:
          type: object
          required: [data]
          properties:
            data:
              type: array
              items: {$ref: '#/components/schemas/Pet'}
            next_cursor: {type: [string, 'null']}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """The synchronous operations of the pets resource."""

    from __future__ import annotations

    from contextlib import AbstractContextManager
    from functools import cached_property
    from typing import Literal

    import models

    from ... import _operations
    from ..._runtime.client.client import ClientCore
    from ...options import UNSET, RequestOptions
    from ...responses import RawResponse, Response
    from ...types.pets import CreatePetResponse, ListPetsResponse


    class PetsResource:
        """The pets operations."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        @cached_property
        def with_response(self) -> PetsWithResponse:
            """The same operations, returning each result with its response metadata."""
            return PetsWithResponse(self._core)

        @cached_property
        def with_raw_response(self) -> PetsWithRawResponse:
            """The same operations, returning each raw response with its body read into memory."""
            return PetsWithRawResponse(self._core)

        @cached_property
        def with_streaming_response(self) -> PetsWithStreamingResponse:
            """The same operations, returning blocks that send each call on entry and stream its response."""
            return PetsWithStreamingResponse(self._core)

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> ListPetsResponse:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            ).data

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> CreatePetResponse:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            ).data


    class PetsWithResponse:
        """The pets operations, returning each result with its response metadata."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[ListPetsResponse]:
            """
            Call GET /pets.
            """
            return self._core.execute(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> Response[CreatePetResponse]:
            """
            Call POST /pets.
            """
            return self._core.execute(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithRawResponse:
        """The pets operations, returning each raw response with its body read into memory."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call GET /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> RawResponse:
            """
            Call POST /pets.
            """
            return self._core.execute_raw(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )


    class PetsWithStreamingResponse:
        """The pets operations, returning blocks that send each call on entry and stream its response."""

        def __init__(self, core: ClientCore) -> None:
            """Keep the client core the operations send through."""
            self._core = core

        def list_pets(
            self,
            *,
            limit: int | UNSET = UNSET,
            cursor: str | UNSET = UNSET,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call GET /pets.
            """
            return self._core.stream(
                _operations.OPERATION_0,
                (limit, cursor),
                options=options,
                response_media_type=response_media_type,
            )

        def create_pet(
            self,
            *,
            body: models.NewPet,
            media_type: Literal['application/json'] | None = None,
            response_media_type: Literal['application/json'] | None = None,
            options: RequestOptions | None = None,
        ) -> AbstractContextManager[RawResponse]:
            """
            Call POST /pets.
            """
            return self._core.stream(
                _operations.OPERATION_1,
                (),
                body=body,
                media_type=media_type,
                options=options,
                response_media_type=response_media_type,
            )
    ```

    <!-- fmt: on -->

---

## `--generate-server` {#generate-server}

Generate a FastAPI server package for the models (experimental).

`--generate-server fastapi` generates the models of an OpenAPI document as usual and, in the same run, a FastAPI
server package at `--server-output`: routers, a service Protocol for each router group, and the application. The
models need the `api` scope (`--openapi-scopes schemas api`), a Pydantic v2 output model type, and a target Python
version of 3.11 or later. Like every server setting, it can also be set in `[tool.datamodel-codegen]` of
pyproject.toml, here as `generate-server = "fastapi"`.

**Option relationships:**

- **Requires:** [`--server-output`](target-generation-options.md#server-output) - `--generate-server` requires `--server-output`.
- **Requires:** [`--server-package`](target-generation-options.md#server-package) - `--generate-server` requires `--server-package`.
- **Requires:** [`--server-model-package`](target-generation-options.md#server-model-package) - `--generate-server` requires `--server-model-package`.
- **Requires:** [`--input-file-type`](base-options.md#input-file-type) = `openapi` - `--generate-server` requires `--input-file-type openapi`.
- **Conflicts:** [`--generate-client`](target-generation-options.md#generate-client) - `--generate-server` can not be used with `--generate-client`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models # (1)!
    ```

    1. :material-arrow-left: `--generate-server` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-body-mode` {#server-body-mode}

Choose how service methods receive request bodies (experimental).

`typed` (the default) passes the body validated as its model; `request` passes the raw Starlette `Request` instead,
for methods that read the body themselves. `--server-body-modes` overrides it for single operations.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-body-mode` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-body-mode request # (1)!
    ```

    1. :material-arrow-left: `--server-body-mode` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi import Request
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            request: Request,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            request: Request,
            name: str,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-body-modes` {#server-body-modes}

Set the body mode of single operations (experimental).

The JSON object, inline or in a file, maps operation references to `typed` or `request`, and overrides
`--server-body-mode` for those operations. A relative document of an operation reference resolves against the JSON file that holds the reference, or
without a file against the working directory, and against the pyproject.toml directory for a table.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-body-modes` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-body-modes '{"/paths/~1pets~1{name}/put": "request"}' # (1)!
    ```

    1. :material-arrow-left: `--server-body-modes` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi import Request
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            request: Request,
            name: str,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-handler-mode` {#server-handler-mode}

Declare the service methods as plain or coroutine functions (experimental).

`sync` (the default) declares plain methods, which FastAPI runs in a thread pool; `async` declares coroutine
methods. `--server-handler-modes` overrides it for single operations.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-handler-mode` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-handler-mode async # (1)!
    ```

    1. :material-arrow-left: `--server-handler-mode` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        async def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        async def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        async def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-handler-modes` {#server-handler-modes}

Set the handler mode of single operations (experimental).

The JSON object, inline or in a file, maps operation references to `sync` or `async`, and overrides
`--server-handler-mode` for those operations. An operation reference is the JSON pointer of the path item method,
such as `/paths/~1pets/get`, optionally after a document and `#`, such as `pets.yaml#/paths/~1pets/get`.
A relative document of an operation reference resolves against the JSON file that holds the reference, or
without a file against the working directory, and against the pyproject.toml directory for a table. In pyproject.toml, `server-handler-modes` is a table, and a command-line value replaces the whole
table.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-handler-modes` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-handler-modes '{"/paths/~1pets/post": "async"}' # (1)!
    ```

    1. :material-arrow-left: `--server-handler-modes` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        async def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-include-request` {#server-include-request}

Pass the Starlette Request to every service method (experimental).

Each service method takes a `request` keyword argument as well as the operation's arguments.
`--no-server-include-request` turns off a `server-include-request = true` of pyproject.toml.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-include-request` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-include-request # (1)!
    ```

    1. :material-arrow-left: `--server-include-request` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi import Request
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            request: Request,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            request: Request,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            request: Request,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-layout` {#server-layout}

Choose how the server package lays out its routes (experimental).

`routers` (the default) writes one router module per tag under `routers/`; `single` writes every route to one
`routes.py` module.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-layout` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-layout single # (1)!
    ```

    1. :material-arrow-left: `--server-layout` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Endpoints of every operation; regenerate them instead of editing."""

    from collections.abc import Sequence
    from typing import Annotated, Final

    import models
    from fastapi import APIRouter, Body, Path, Query, params
    from fastapi.responses import Response

    from ._generated import contract
    from ._generated.contract import OperationDependencies
    from ._runtime.server.application import Wiring, build, checked
    from ._runtime.server.responses import dispatch
    from .services import Service


    def _add_list_pets(
        router: APIRouter,
        wiring: Wiring,
    ) -> None:
        service: Service = wiring.services['service']
        list_pets_handler = checked(
            service.list_pets,
            'The service.list_pets method of GET /pets',
            ('limit',),
        )

        def list_pets(
            *,
            limit: Annotated[int, Query(alias='limit')] = 20,
        ) -> object:
            return dispatch(
                list_pets_handler(
                    limit=limit,
                ),
                contract.ListPets.RESPONSES,
            )

        router.add_api_route(
            '/pets',
            list_pets,
            methods=['GET'],
            status_code=200,
            response_model=models.PetsGetResponse,
            response_model_by_alias=True,
            response_model_exclude_unset=True,
            operation_id='listPets',
            tags=['pets'],
            response_description='The pets.',
            dependencies=wiring.dependencies.get('list_pets'),
        )


    def _add_create_pet(
        router: APIRouter,
        wiring: Wiring,
    ) -> None:
        service: Service = wiring.services['service']
        create_pet_handler = checked(
            service.create_pet,
            'The service.create_pet method of POST /pets',
            ('body',),
        )

        def create_pet(
            *,
            body: Annotated[models.Pet, Body(media_type='application/json')],
        ) -> object:
            return dispatch(
                create_pet_handler(
                    body=body,
                ),
                contract.CreatePet.RESPONSES,
            )

        router.add_api_route(
            '/pets',
            create_pet,
            methods=['POST'],
            status_code=200,
            response_model=models.Pet,
            response_model_by_alias=True,
            response_model_exclude_unset=True,
            operation_id='createPet',
            tags=['pets'],
            response_description='Already there.',
            dependencies=wiring.dependencies.get('create_pet'),
        )


    def _add_replace_pet(
        router: APIRouter,
        wiring: Wiring,
    ) -> None:
        service: Service = wiring.services['service']
        replace_pet_handler = checked(
            service.replace_pet,
            'The service.replace_pet method of PUT /pets/{name}',
            ('name', 'body'),
        )

        def replace_pet(
            *,
            name: Annotated[str, Path(alias='name')],
            body: Annotated[models.Pet, Body(media_type='application/json')],
        ) -> object:
            return dispatch(
                replace_pet_handler(
                    name=name,
                    body=body,
                ),
                contract.ReplacePet.RESPONSES,
            )

        router.add_api_route(
            '/pets/{name}',
            replace_pet,
            methods=['PUT'],
            status_code=204,
            response_model=None,
            response_class=Response,
            operation_id='replacePet',
            tags=['pets'],
            response_description='Replaced.',
            dependencies=wiring.dependencies.get('replace_pet'),
        )


    LITERAL_ROUTES: Final = (
        ('list_pets', _add_list_pets),
        ('create_pet', _add_create_pet),
    )
    TEMPLATED_ROUTES: Final = (
        ('replace_pet', _add_replace_pet),
    )


    def build_router(
        *,
        service: Service,
        dependencies: Sequence[params.Depends] = (),
        operation_dependencies: OperationDependencies | None = None,
        prefix: str = "",
    ) -> APIRouter:
        """Register every operation on a new router, literal paths first."""
        return build(
            (*LITERAL_ROUTES, *TEMPLATED_ROUTES),
            services={'service': service},
            dependencies=dependencies,
            operation_dependencies=operation_dependencies,
            prefix=prefix,
        )
    ```

    <!-- fmt: on -->

---

## `--server-model-package` {#server-model-package}

Name the import path of the models the server package imports (experimental).

`--server-model-package` is required with `--generate-server`, and names the module or package `--output`
generates.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-model-package` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models # (1)!
    ```

    1. :material-arrow-left: `--server-model-package` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-operation-names` {#server-operation-names}

Name the service methods of single operations (experimental).

The JSON object, inline or in a file, maps operation references to method names. Other operations take the
snake_case form of their operationId, or of their method and path. A relative document of an operation reference resolves against the JSON file that holds the reference, or
without a file against the working directory, and against the pyproject.toml directory for a table.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-operation-names` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-operation-names '{"/paths/~1pets/get": "list_all"}' # (1)!
    ```

    1. :material-arrow-left: `--server-operation-names` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_all(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-output` {#server-output}

Write the server package to this directory (experimental).

`--server-output` is required with `--generate-server`. A path given on the command line is relative to the working
directory, and the `server-output` key of pyproject.toml is relative to the pyproject.toml directory, as for
`--output`.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-output` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models # (1)!
    ```

    1. :material-arrow-left: `--server-output` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-package` {#server-package}

Name the import path of the server package (experimental).

`--server-package` is required with `--generate-server`. The generated README and the dependency command a
generation prints name the package by it; the package imports its own modules relatively.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-package` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models # (1)!
    ```

    1. :material-arrow-left: `--server-package` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-parameter-names` {#server-parameter-names}

Name the method arguments of single operations (experimental).

The JSON object, inline or in a file, maps operation references to objects that map a parameter, written as its
location and name such as `query:limit` or `header:X-Request-Id`, to the argument name. A relative document of an operation reference resolves against the JSON file that holds the reference, or
without a file against the working directory, and against the pyproject.toml directory for a table.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-parameter-names` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-parameter-names '{"/paths/~1pets/get": {"query:limit": "page_size"}}' # (1)!
    ```

    1. :material-arrow-left: `--server-parameter-names` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class PetsService(Protocol):
        """Implement the pets operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            page_size: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

## `--server-primary-responses` {#server-primary-responses}

Choose the response a bare return value of an operation takes (experimental).

The JSON object, inline or in a file, maps operation references to an object with a `status_code` and, when the
response has several media types, its `media_type`. The `status_code` takes the response that declares that status
exactly, by its range such as `2XX`, or as `default`. Without an entry, the primary response is `200` when the
operation declares it, or else its lowest success status, or else its `2XX` or else its `default` response, sent as
`200`, or else its lowest status; an operation that declares only other ranges, such as `4XX`, has none.
A relative document of an operation reference resolves against the JSON file that holds the reference, or
without a file against the working directory, and against the pyproject.toml directory for a table.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-primary-responses` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-primary-responses '{"/paths/~1pets/post": {"status_code": 201}}' # (1)!
    ```

    1. :material-arrow-left: `--server-primary-responses` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Endpoints of the pets operations; regenerate them instead of editing."""

    from collections.abc import Sequence
    from typing import Annotated, Final

    import models
    from fastapi import APIRouter, Body, Path, Query, params
    from fastapi.responses import Response

    from .._generated import contract
    from .._generated.contract import OperationDependencies
    from .._runtime.server.application import Wiring, build, checked
    from .._runtime.server.responses import dispatch
    from ..services import PetsService


    def _add_list_pets(
        router: APIRouter,
        wiring: Wiring,
    ) -> None:
        pets: PetsService = wiring.services['pets']
        list_pets_handler = checked(
            pets.list_pets,
            'The pets.list_pets method of GET /pets',
            ('limit',),
        )

        def list_pets(
            *,
            limit: Annotated[int, Query(alias='limit')] = 20,
        ) -> object:
            return dispatch(
                list_pets_handler(
                    limit=limit,
                ),
                contract.ListPets.RESPONSES,
            )

        router.add_api_route(
            '/pets',
            list_pets,
            methods=['GET'],
            status_code=200,
            response_model=models.PetsGetResponse,
            response_model_by_alias=True,
            response_model_exclude_unset=True,
            operation_id='listPets',
            tags=['pets'],
            response_description='The pets.',
            dependencies=wiring.dependencies.get('list_pets'),
        )


    def _add_create_pet(
        router: APIRouter,
        wiring: Wiring,
    ) -> None:
        pets: PetsService = wiring.services['pets']
        create_pet_handler = checked(
            pets.create_pet,
            'The pets.create_pet method of POST /pets',
            ('body',),
        )

        def create_pet(
            *,
            body: Annotated[models.Pet, Body(media_type='application/json')],
        ) -> object:
            return dispatch(
                create_pet_handler(
                    body=body,
                ),
                contract.CreatePet.RESPONSES,
            )

        router.add_api_route(
            '/pets',
            create_pet,
            methods=['POST'],
            status_code=201,
            response_model=models.Pet,
            response_model_by_alias=True,
            response_model_exclude_unset=True,
            operation_id='createPet',
            tags=['pets'],
            response_description='Created.',
            dependencies=wiring.dependencies.get('create_pet'),
        )


    def _add_replace_pet(
        router: APIRouter,
        wiring: Wiring,
    ) -> None:
        pets: PetsService = wiring.services['pets']
        replace_pet_handler = checked(
            pets.replace_pet,
            'The pets.replace_pet method of PUT /pets/{name}',
            ('name', 'body'),
        )

        def replace_pet(
            *,
            name: Annotated[str, Path(alias='name')],
            body: Annotated[models.Pet, Body(media_type='application/json')],
        ) -> object:
            return dispatch(
                replace_pet_handler(
                    name=name,
                    body=body,
                ),
                contract.ReplacePet.RESPONSES,
            )

        router.add_api_route(
            '/pets/{name}',
            replace_pet,
            methods=['PUT'],
            status_code=204,
            response_model=None,
            response_class=Response,
            operation_id='replacePet',
            tags=['pets'],
            response_description='Replaced.',
            dependencies=wiring.dependencies.get('replace_pet'),
        )


    LITERAL_ROUTES: Final = (
        ('list_pets', _add_list_pets),
        ('create_pet', _add_create_pet),
    )
    TEMPLATED_ROUTES: Final = (
        ('replace_pet', _add_replace_pet),
    )


    def build_router(
        *,
        pets: PetsService,
        dependencies: Sequence[params.Depends] = (),
        operation_dependencies: OperationDependencies | None = None,
        prefix: str = "",
    ) -> APIRouter:
        """Register the pets operations on a new router, literal paths first."""
        return build(
            (*LITERAL_ROUTES, *TEMPLATED_ROUTES),
            services={'pets': pets},
            dependencies=dependencies,
            operation_dependencies=operation_dependencies,
            prefix=prefix,
        )
    ```

    <!-- fmt: on -->

---

## `--server-router-names` {#server-router-names}

Name router groups (experimental).

The JSON object, inline or in a file, maps group keys, such as `tag:pets` for the operations whose first tag is
`pets`, to the name of the router module, the `create_app` argument, and the `<Name>Service` Protocol.

**Option relationships:**

- **Requires:** [`--generate-server`](target-generation-options.md#generate-server) - `--server-router-names` requires `--generate-server fastapi`.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input options.yaml --input-file-type openapi --output models.py --target-python-version 3.11 --openapi-scopes schemas api --output-model-type pydantic_v2.BaseModel --formatters builtin --disable-timestamp --generate-server fastapi --server-output server --server-package server --server-model-package models --server-router-names '{"tag:pets": "animals"}' # (1)!
    ```

    1. :material-arrow-left: `--server-router-names` - the option documented here

??? example "Examples"

    **Input Schema:**

    ```yaml
    openapi: 3.1.0
    info: {title: Pets, version: "1.0"}
    paths:
      /pets:
        get:
          operationId: listPets
          tags: [pets]
          parameters:
            - {name: limit, in: query, schema: {type: integer, default: 20}}
          responses:
            "200":
              description: The pets.
              content:
                application/json:
                  schema: {type: array, items: {$ref: "#/components/schemas/Pet"}}
        post:
          operationId: createPet
          tags: [pets]
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "200":
              description: Already there.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
            "201":
              description: Created.
              content:
                application/json:
                  schema: {$ref: "#/components/schemas/Pet"}
      /pets/{name}:
        put:
          operationId: replacePet
          tags: [pets]
          parameters:
            - {name: name, in: path, required: true, schema: {type: string}}
          requestBody:
            required: true
            content:
              application/json:
                schema: {$ref: "#/components/schemas/Pet"}
          responses:
            "204": {description: Replaced.}
    components:
      schemas:
        Pet:
          type: object
          required: [name]
          properties:
            name: {type: string}
    ```

    **Output:**

    <!-- fmt: off -->

    ```python
    # generated by datamodel-codegen:
    #   filename:  options.yaml

    """Service interfaces of this package's router groups; regenerate them instead of editing."""

    from __future__ import annotations

    from abc import abstractmethod
    from typing import Protocol

    import models
    from fastapi.responses import Response

    from ._runtime.server.responses import HTTPResult


    class AnimalsService(Protocol):
        """Implement the animals operations: subclass this Protocol, or give an object its methods."""

        @abstractmethod
        def list_pets(
            self,
            *,
            limit: int,
        ) -> models.PetsGetResponse | HTTPResult[models.PetsGetResponse] | Response:
            """
            Handle GET /pets.
            """

        @abstractmethod
        def create_pet(
            self,
            *,
            body: models.Pet,
        ) -> models.Pet | HTTPResult[models.Pet] | Response:
            """
            Handle POST /pets.
            """

        @abstractmethod
        def replace_pet(
            self,
            *,
            name: str,
            body: models.Pet,
        ) -> None | HTTPResult[None] | Response:
            """
            Handle PUT /pets/{name}.
            """
    ```

    <!-- fmt: on -->

---

---

# Utility Options

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/utility-options/

## 📋 Options

| Option | Description |
|--------|-------------|
| [`--all-jobs`](#all-jobs) | Run every named generation job from pyproject.toml (experimental) |
| [`--debug`](#debug) | Show debug messages during code generation |
| [`--generate-prompt`](#generate-prompt) | Generate a prompt for consulting LLMs about CLI options |
| [`--help`](#help) | Show help message and exit |
| [`--install-skill`](#install-skill) | Install the bundled Agent Skill (experimental) |
| [`--job`](#job) | Run a named generation job from pyproject.toml (experimental) |
| [`--list-deprecations`](#list-deprecations) | List registered deprecations and scheduled breaking changes |
| [`--list-experimental`](#list-experimental) | List registered experimental features |
| [`--no-color`](#no-color) | Disable colorized output |
| [`--output-format`](#output-format) | Choose the command output format |
| [`--output-format-json-schema`](#output-format-json-schema) | Output JSON Schema for structured command output or JSON configuration |
| [`--overwrite-skill`](#overwrite-skill) | Replace an existing Agent Skill installation |
| [`--profile`](#profile) | Use a named profile from pyproject.toml |
| [`--skill-scope`](#skill-scope) | Choose an Agent Skill installation scope |
| [`--version`](#version) | Show program version and exit |

---

## `--all-jobs` {#all-jobs}

Run every named generation job from `[tool.datamodel-codegen.jobs]` in declaration
order (experimental).

!!! warning "Experimental"

    Named batch jobs are experimental; their configuration schema, batch output,
    and transactional/watch execution contracts may change.

**Related:** [`--job`](#job), [`--diff-against`](general-options.md#diff-against),
[pyproject.toml Configuration](../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --all-jobs
    datamodel-codegen --all-jobs --check
    datamodel-codegen --all-jobs --output-format json
    datamodel-codegen --all-jobs --watch
    ```

All selected jobs are validated before generation starts. Jobs that write to
stdout, or whose output or model-metadata paths overlap, are rejected before
any generated file is written. With `--output-format json`, one `batch`
payload contains the result of every job.

`--diff-against` is intentionally unavailable for every named-job execution,
including a single selected job. Keeping one contract across `--job` and
`--all-jobs` avoids ambiguous partial support when the selection grows. Run the
comparison for one profile or input instead.

With `--watch`, changes to `pyproject.toml` replan the complete job membership.
All selected local dependencies are watched as one graph, and every event reruns
and publishes the whole batch transactionally rather than rebuilding only one
job.

---

## `--debug` {#debug}

Show debug messages during code generation.

Enables verbose debug output to help troubleshoot issues with schema parsing
or code generation. Requires the `debug` extra to be installed.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --debug # (1)!
    ```

    1. :material-arrow-left: `--debug` - the option documented here

!!! warning "Requires extra dependency"

    The debug feature requires the `debug` extra:

    ```bash
    pip install 'datamodel-code-generator[debug]'
    ```

---

## `--generate-prompt` {#generate-prompt}

Generate a prompt for consulting LLMs about CLI options.

Outputs a formatted prompt containing your current options, all available
options by category, and full help text. Pipe to CLI LLM tools or copy
to clipboard for web-based LLM chats.

Use `--output-format json` when an LLM agent or tool should consume structured
option metadata instead of Markdown.
Use `--output-format-json-schema generate-prompt` when the agent needs the JSON
Schema for that structured payload, such as when defining a tool contract.

**See also:** [LLM Integration](../llm-integration.md) for detailed usage examples

!!! note "For LLM agents"

    See [LLM Integration: If You Are an LLM Agent](../llm-integration.md#if-you-are-an-llm-agent)
    for workflow guidance.

!!! tip "Usage"

    ```bash
    datamodel-codegen --generate-prompt # (1)!
    datamodel-codegen --generate-prompt "How do I generate strict types?" # (2)!
    datamodel-codegen --generate-prompt --output-format json # (3)!
    datamodel-codegen --output-format-json-schema generate-prompt # (4)!
    ```

    1. :material-arrow-left: `--generate-prompt` - generate prompt without a question
    2. :material-arrow-left: Include a specific question in the prompt
    3. :material-arrow-left: Emit structured JSON for LLM/tool ingestion
    4. :material-arrow-left: Emit JSON Schema for structured prompt JSON

??? example "Quick Examples"

    **Pipe to CLI tools:**
    ```bash
    datamodel-codegen --generate-prompt | claude -p    # Claude Code
    datamodel-codegen --generate-prompt | codex exec   # OpenAI Codex
    datamodel-codegen --generate-prompt --output-format json | codex exec
    ```

    **Copy to clipboard:**
    ```bash
    datamodel-codegen --generate-prompt | pbcopy      # macOS
    datamodel-codegen --generate-prompt | xclip -selection clipboard  # Linux
    datamodel-codegen --generate-prompt | clip.exe    # WSL2
    ```

    **Ask about an existing OpenAPI command:**
    ```bash
    datamodel-codegen \
        --input openapi.yaml \
        --input-file-type openapi \
        --output models.py \
        --output-model-type pydantic_v2.BaseModel \
        --target-python-version 3.12 \
        --generate-prompt "Find the minimal options for strict API response models." \
        | claude -p
    ```

    **Review a command with current options:**
    ```bash
    datamodel-codegen \
        --input schema.json \
        --output models.py \
        --output-model-type pydantic_v2.BaseModel \
        --generate-prompt "Review this command for stable generated output in CI." \
        | claude -p
    ```

---

## `--help` {#help}

Show help message and exit.

Displays all available command-line options with their descriptions and default values.

**Aliases:** `-h`

!!! tip "Usage"

    ```bash
    datamodel-codegen --help # (1)!
    ```

    1. :material-arrow-left: `--help` - the option documented here

??? example "Output"

    ```text
    usage: datamodel-codegen [-h] [--input INPUT] [--url URL] ...

    Generate Python data models from schema files.

    options:
      -h, --help            show this help message and exit
      --input INPUT         Input file path (default: stdin)
      ...
    ```

---

## `--install-skill` {#install-skill}

Install the bundled experimental `datamodel-code-generator` Agent Skill for Codex or Claude Code, then exit.

The default `project` scope installs the skill in the current project's
`.agents/skills/` directory for Codex or `.claude/skills/` directory for Claude
Code. Use `--skill-scope user` to install the same skill below your home
directory instead.

!!! tip "Usage"

    ```bash
    datamodel-codegen --install-skill codex # (1)!
    datamodel-codegen --install-skill claude-code --skill-scope user # (2)!
    datamodel-codegen --install-skill codex --overwrite-skill # (3)!
    ```

    1. :material-arrow-left: Install for Codex in `.agents/skills/` for the current project
    2. :material-arrow-left: Install for Claude Code in `~/.claude/skills/`
    3. :material-arrow-left: Replace an existing regular skill directory

For safety, an existing skill directory is left untouched unless
`--overwrite-skill` is supplied. Symlinks and non-directory targets are never
replaced.

---

## `--job` {#job}

Run one or more named generation jobs declared in `pyproject.toml` (experimental). Jobs are
executed sequentially in TOML declaration order, even when `--job` is supplied
in a different order.

!!! warning "Experimental"

    Named batch jobs are experimental; their configuration schema, batch output,
    and transactional/watch execution contracts may change.

**Related:** [pyproject.toml Configuration](../pyproject_toml.md),
[`--all-jobs`](#all-jobs), [`--diff-against`](general-options.md#diff-against)

!!! tip "Usage"

    ```bash
    datamodel-codegen --job api
    datamodel-codegen --job api --job events --check
    ```

??? example "Configuration (pyproject.toml)"

    ```toml
    [tool.datamodel-codegen.profiles.strict]
    use-annotated = true

    [tool.datamodel-codegen.jobs.api]
    profile = "strict"
    input = "schemas/openapi.yaml"
    output = "src/models/api.py"

    [tool.datamodel-codegen.jobs.events]
    input = "schemas/events.json"
    output = "src/models/events.py"
    ```

Jobs require their own `input` and `output`. A job can select one reusable
profile using `profile = "name"`. Settings are resolved as base configuration,
job profile, job settings, then safe batch-wide CLI overrides. `--input`,
`--url`, `--input-model`, `--output`, and `--profile` cannot be combined with
job selection. `--diff-against` also cannot be combined with named jobs: compare
one profile or input at a time. With `--watch`, one outer scheduler watches the
selected jobs' combined dependency graph and `pyproject.toml`. Every event replans and
transactionally reruns the complete selection; failures retain the published
outputs and continue watching for recovery.

A job whose settings select `generate-server` also generates the FastAPI server
package, and such jobs can share one models `output`; see [Batch jobs](../fastapi-server.md#batch-jobs).

---

## `--list-deprecations` {#list-deprecations}

List registered deprecations and scheduled breaking changes, then exit.

The option reads from the central deprecation registry used by runtime warnings,
generated documentation, and release-note snippets.

    datamodel-codegen --list-deprecations
    datamodel-codegen --list-deprecations json
    datamodel-codegen --list-deprecations markdown

---

## `--list-experimental` {#list-experimental}

List registered experimental features, then exit.

The optional format argument can be `table`, `json`, or `markdown`. The default is `table`.

The option reads from the central experimental feature registry used by
generated documentation and release-note snippets.

    datamodel-codegen --list-experimental
    datamodel-codegen --list-experimental json
    datamodel-codegen --list-experimental markdown

---

## `--no-color` {#no-color}

Disable colorized output.

By default, datamodel-codegen uses colored output for better readability.
Use this option to disable colors, which is useful for CI/CD pipelines
or when redirecting output to files.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --no-color # (1)!
    ```

    1. :material-arrow-left: `--no-color` - the option documented here

!!! note "Environment variable"

    You can also disable colors by setting the `NO_COLOR` environment variable:

    ```bash
    NO_COLOR=1 datamodel-codegen --input schema.json
    ```

---

## `--output-format` {#output-format}

Choose the command output format.

The default output format is `text`. Use `json` when another program or LLM
agent should inspect structured output.

For backward compatibility, text stdout concatenates generated modules and does
not preserve their paths. Use `--fail-on-multi-module-stdout` to reject that
case, `--output <directory>` to preserve files, or `--output-format json` for
structured stdout. The fail option takes precedence over automatic repair of an
unusable modular stdout result, so an explicitly requested guard always rejects
the modular result instead of coalescing it.

In normal generation mode, `--output-format json` wraps generated modules in a
structured payload on stdout. If `--output` is also supplied, files are still
written to disk and the JSON payload mirrors the generated files. `--check`
also supports JSON output for difference reports. `--watch` keeps its existing
text output contract and does not support `--output-format json`.

Structured JSON is emitted on stdout for successful commands and for `--check`
difference reports. CLI usage errors, validation errors, and runtime generation
errors continue to use text on stderr with a non-zero exit code.

Generation JSON includes the normalized requested output path in top-level
`output` when `--output` is supplied, or `null` for stdout generation.
`files[].path` is the output file name for single-file disk output, and the
path relative to the output directory for directory output. For stdout-only
single-file generation it is `null`, and for multi-module stdout generation it
is the generated module path.

With `--generate-server` or `--generate-client`, the generation, check, and
input-diff payloads also have a `target` object: `package` is the import path
of the generated package, and `dependencies` lists its runtime requirements as
PEP 508 strings, the ones the `uv add` command on stderr names. A check or input
diff lists those of the current input, and `implied` the model settings the run
left unset and the target set, when there are any: an object with the keys
`openapi-scopes`, `target-python-version`, `use-missing-sentinel`,
`target-pydantic-version`, `use-msgspec-tagged-unions`, and
`use-msgspec-nullable-enum-alias`, each present only when the target set it. Payloads of model-only generation leave `target` out. The generation payload's `target` also carries the next steps that
stderr prints: `readme`, the path of the package README; for a server,
`entrypoint` (`app`, the import string of the application in `main.py`, and
`path`) and `implementation`, one entry for each module of yours that `main.py`
imports (`module`, `name`, `path`, and `created`, true when the run wrote it with
stubs, and whose `path` names the `__init__.py` of a module you made a package);
and for a client, `usage`, code that calls its first operation. Its paths are
relative like those of `files`.

Use `--output-format json` with `--generate-prompt` to emit structured option
metadata instead of Markdown. Use `--output-format-json-schema` when an LLM
agent or tool needs the schema for a JSON payload.

Schema targets are intentionally scoped. `generate-prompt` emits the
`PromptPayload` schema for `--generate-prompt --output-format json`.
`generation` emits only the `GenerationPayload` schema for generated-file JSON.
`model-metadata` emits the schema for files written by `--emit-model-metadata`.
`structured-output` emits the broader `StructuredOutputPayload` schema, a union
covering `GenerationPayload`, `PromptPayload`, `CommandOutputPayload`, and
`CheckOutputPayload`. Structured payloads use `kind` as the discriminator.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --output-format text # (1)!
    datamodel-codegen --input schema.json --output-format json # (2)!
    datamodel-codegen --generate-prompt --output-format json # (3)!
    datamodel-codegen --output-format-json-schema generation # (4)!
    datamodel-codegen --output-format-json-schema generate-prompt # (5)!
    datamodel-codegen --output-format-json-schema model-metadata # (6)!
    datamodel-codegen --output-format-json-schema structured-output # (7)!
    ```

    1. :material-arrow-left: Emit the default generated Python text
    2. :material-arrow-left: Emit structured JSON containing generated files
    3. :material-arrow-left: Emit structured JSON with current options and argparse metadata
    4. :material-arrow-left: Emit JSON Schema for generated-file JSON output
    5. :material-arrow-left: Emit JSON Schema for structured prompt JSON
    6. :material-arrow-left: Emit JSON Schema for generated model metadata JSON
    7. :material-arrow-left: Emit JSON Schema for any structured command JSON output

??? example "Generation JSON output"

    ```json
    {
      "version": 1,
      "format": "json",
      "kind": "generation",
      "output": null,
      "files": [
        {
          "path": null,
          "content": "# generated by datamodel-codegen:\n..."
        }
      ]
    }
    ```

??? example "Prompt JSON output"

    ```bash
    datamodel-codegen \
        --input schema.json \
        --output-model-type pydantic_v2.BaseModel \
        --generate-prompt "Choose strict model options." \
        --output-format json
    ```

---

## `--output-format-json-schema` {#output-format-json-schema}

Output JSON Schema for a JSON output format and exit.

Use this when an LLM agent, tool call definition, or validation layer needs the
contract before consuming JSON output. The schema is emitted separately from the
JSON payload so tools can fetch the contract once and validate later command
output independently.

Currently supported schema targets:

- `generate-prompt`: schema for `--generate-prompt --output-format json`
- `generation`: schema for normal generation with `--output-format json`
- `model-metadata`: schema for files emitted by `--emit-model-metadata`
- `structured-output`: tagged union schema for all structured command outputs,
  discriminated by `kind`
- `config`: schema for JSON-valued configuration options

!!! tip "Usage"

    ```bash
    datamodel-codegen --output-format-json-schema generate-prompt # (1)!
    datamodel-codegen --output-format-json-schema generation # (2)!
    datamodel-codegen --output-format-json-schema model-metadata # (3)!
    datamodel-codegen --output-format-json-schema structured-output # (4)!
    datamodel-codegen --output-format-json-schema config # (5)!
    datamodel-codegen --generate-prompt --output-format json # (6)!
    datamodel-codegen --input schema.json --emit-model-metadata model-map.json # (7)!
    ```

    1. :material-arrow-left: Emit the JSON Schema for structured prompt output
    2. :material-arrow-left: Emit the JSON Schema for generated-file output
    3. :material-arrow-left: Emit the JSON Schema for generated model metadata
    4. :material-arrow-left: Emit the JSON Schema for all structured command outputs
    5. :material-arrow-left: Emit the JSON Schema for JSON-valued configuration options
    6. :material-arrow-left: Emit prompt payloads that match the prompt schema
    7. :material-arrow-left: Emit metadata payloads that match the model metadata schema

---

## `--overwrite-skill` {#overwrite-skill}

Replace an existing regular Agent Skill directory when installing with
`--install-skill`.

Without this option, an existing skill is preserved and the command exits with
an error. Symlinks and non-directory targets are never overwritten.

    datamodel-codegen --install-skill codex --overwrite-skill

---

## `--profile` {#profile}

Use a named profile from pyproject.toml configuration.

Profiles allow you to define multiple named configurations in your pyproject.toml
file. Each profile can override the default settings with its own set of options.

**Related:** [pyproject.toml Configuration](../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --profile strict # (1)!
    ```

    1. :material-arrow-left: `--profile` - the option documented here

??? example "Configuration (pyproject.toml)"

    ```toml
    [tool.datamodel-codegen]
    # Default configuration
    output-model-type = "pydantic_v2.BaseModel"

    [tool.datamodel-codegen.profiles.strict]
    # Strict profile with additional options
    strict-types = ["str", "int", "float", "bool"]
    strict-nullable = true

    [tool.datamodel-codegen.profiles.dataclass]
    # Dataclass profile
    output-model-type = "dataclasses.dataclass"
    ```

    Use profiles:

    ```bash
    # Use the strict profile
    datamodel-codegen --input schema.json --profile strict

    # Use the dataclass profile
    datamodel-codegen --input schema.json --profile dataclass
    ```

---

## `--skill-scope` {#skill-scope}

Choose whether `--install-skill` installs the bundled Agent Skill for the
current project or for the current user. The default is `project`.

`project` uses `.agents/skills/` for Codex and `.claude/skills/` for Claude
Code below the current working directory. `user` uses the matching directory
below your home directory.

    datamodel-codegen --install-skill codex --skill-scope project
    datamodel-codegen --install-skill claude-code --skill-scope user

---

## `--version` {#version}

Show program version and exit.

Displays the installed version of datamodel-code-generator.

!!! tip "Usage"

    ```bash
    datamodel-codegen --version # (1)!
    ```

    1. :material-arrow-left: `--version` - the option documented here

??? example "Output"

    ```text
    datamodel-codegen version: 0.x.x
    ```

---

---

# Model Customization

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/topics/model-customization/

Choose model class shape, naming, reuse, and root-model behavior.

Options are grouped from shared CLI metadata and link back to their generated reference sections.

## Groups

| Group | Options | Description |
|-------|---------|-------------|
| [Model Naming](#model-naming) | 9 | Class names, suffixes, prefixes, and duplicate-name behavior. |
| [Model Reuse](#model-reuse) | 4 | Schema deduplication and shared generated modules. |
| [Model Shape](#model-shape) | 6 | Output model family and compatibility targets. |
| [Root Model](#root-model) | 4 | Root model creation, collapse, and alias behavior. |

## Model Naming {#model-naming}

Class names, suffixes, prefixes, and duplicate-name behavior.

| Option | Description |
|--------|-------------|
| [`--allow-leading-underscore-class-name`](../model-customization.md#allow-leading-underscore-class-name) | Allow an explicitly specified root class name to start with an underscore. |
| [`--class-name`](../model-customization.md#class-name) | Override the auto-generated class name with a custom name. |
| [`--class-name-affix-scope`](../model-customization.md#class-name-affix-scope) | Control which classes receive the prefix/suffix. |
| [`--class-name-prefix`](../model-customization.md#class-name-prefix) | Add a prefix to all generated class names. |
| [`--class-name-suffix`](../model-customization.md#class-name-suffix) | Add a suffix to all generated class names. |
| [`--duplicate-name-suffix`](../model-customization.md#duplicate-name-suffix) | Customize suffix for duplicate model names. |
| [`--model-name-map`](../model-customization.md#model-name-map) | Rename generated model classes from a JSON mapping. |
| [`--naming-strategy`](../model-customization.md#naming-strategy) | Use parent-prefixed naming strategy for duplicate model names. |
| [`--parent-scoped-naming`](../model-customization.md#parent-scoped-naming) | Namespace models by their parent scope to avoid naming conflicts. |

## Model Reuse {#model-reuse}

Schema deduplication and shared generated modules.

| Option | Description |
|--------|-------------|
| [`--collapse-reuse-models`](../model-customization.md#collapse-reuse-models) | Collapse duplicate models by replacing references instead of inheritance. |
| [`--reuse-model`](../model-customization.md#reuse-model) | Reuse identical model definitions instead of generating duplicates. |
| [`--reuse-scope`](../model-customization.md#reuse-scope) | Scope for model reuse detection (root or tree). |
| [`--shared-module-name`](../general-options.md#shared-module-name) | Customize the name of the shared module for deduplicated models. |

## Model Shape {#model-shape}

Output model family and compatibility targets.

| Option | Description |
|--------|-------------|
| [`--base-class`](../model-customization.md#base-class) | Specify a custom base class for generated models. |
| [`--base-class-map`](../model-customization.md#base-class-map) | Specify different base classes for specific models via JSON mapping. |
| [`--output-model-type`](../model-customization.md#output-model-type) | Select the output model type (Pydantic v2, Pydantic v2 dataclass, dataclasses, T... |
| [`--target-pydantic-version`](../model-customization.md#target-pydantic-version) | Target Pydantic version for generated code compatibility. |
| [`--target-python-version`](../model-customization.md#target-python-version) | Target Python version for generated code syntax and imports. |
| [`--use-generic-base-class`](../model-customization.md#use-generic-base-class) | Generate a shared base class with model configuration to avoid repetition (DRY). |

## Root Model {#root-model}

Root model creation, collapse, and alias behavior.

| Option | Description |
|--------|-------------|
| [`--collapse-root-models`](../model-customization.md#collapse-root-models) | Inline root model definitions instead of creating separate wrapper classes. |
| [`--collapse-root-models-name-strategy`](../model-customization.md#collapse-root-models-name-strategy) | Select which name to keep when collapsing root models with object references. |
| [`--skip-root-model`](../model-customization.md#skip-root-model) | Skip generation of root model when schema contains nested definitions. |
| [`--use-root-model-sequence-interface`](../model-customization.md#use-root-model-sequence-interface) | Make non-null sequence-like Pydantic v2 RootModel classes implement collections.... |

---

# Template Customization

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/topics/template-customization/

Tune generated file headers, imports, decorators, templates, and formatting.

Options are grouped from shared CLI metadata and link back to their generated reference sections.

## Groups

| Group | Options | Description |
|-------|---------|-------------|
| [Custom Templates](#custom-templates) | 3 | Custom templates and extra template data. |
| [Generated Output](#generated-output) | 9 | Generated file headers and reproducible output. |
| [Imports](#imports) | 4 | Generated imports and type-checking import behavior. |
| [Output Formatting](#output-formatting) | 5 | Formatter selection, quote style, and string wrapping. |

## Custom Templates {#custom-templates}

Custom templates and extra template data.

| Option | Description |
|--------|-------------|
| [`--custom-template-dir`](../template-customization.md#custom-template-dir) | Use custom Jinja2 templates for model generation. |
| [`--extra-template-data`](../template-customization.md#extra-template-data) | Pass custom template variables via inline JSON or a JSON file path. |
| [`--validators`](../template-customization.md#validators) | Add custom field validators to generated Pydantic v2 models. |

## Generated Output {#generated-output}

Generated file headers and reproducible output.

| Option | Description |
|--------|-------------|
| [`--class-decorators`](../template-customization.md#class-decorators) | Add custom decorators to generated model classes. |
| [`--custom-file-header`](../template-customization.md#custom-file-header) | Add custom header text to the generated file. |
| [`--custom-file-header-mode`](../template-customization.md#custom-file-header-mode) | Choose how a custom file header combines with generated provenance. |
| [`--custom-file-header-path`](../template-customization.md#custom-file-header-path) | Add custom header content from file to generated code. |
| [`--disable-timestamp`](../template-customization.md#disable-timestamp) | Disable timestamp in generated file header for reproducible output. |
| [`--enable-command-header`](../template-customization.md#enable-command-header) | Include command-line options in file header for reproducibility. |
| [`--enable-generated-header-marker`](../template-customization.md#enable-generated-header-marker) | Include the @generated marker in file header for generated-code tooling. |
| [`--enable-version-header`](../template-customization.md#enable-version-header) | Include tool version information in file header. |
| [`--strict-dotted-module-names`](../template-customization.md#strict-dotted-module-names) | Require canonical Python identifiers when inferring dotted module paths. |

## Imports {#imports}

Generated imports and type-checking import behavior.

| Option | Description |
|--------|-------------|
| [`--additional-imports`](../template-customization.md#additional-imports) | Add custom imports to generated output files. |
| [`--no-use-type-checking-imports`](../template-customization.md#no-use-type-checking-imports) | Keep generated model imports available at runtime when using Ruff fixes. |
| [`--use-exact-imports`](../template-customization.md#use-exact-imports) | Import exact types instead of modules. |
| [`--use-type-checking-imports`](../template-customization.md#use-type-checking-imports) | Allow Ruff to move typing-only imports into TYPE_CHECKING blocks. |

## Output Formatting {#output-formatting}

Formatter selection, quote style, and string wrapping.

| Option | Description |
|--------|-------------|
| [`--custom-formatters`](../template-customization.md#custom-formatters) | Apply custom Python code formatters to generated output. |
| [`--custom-formatters-kwargs`](../template-customization.md#custom-formatters-kwargs) | Pass custom arguments to custom formatters via inline JSON or a JSON file path. |
| [`--formatters`](../template-customization.md#formatters) | Specify code formatters to apply to generated output. |
| [`--use-double-quotes`](../template-customization.md#use-double-quotes) | Use double quotes for string literals in generated code. |
| [`--wrap-string-literal`](../template-customization.md#wrap-string-literal) | Wrap long string literals across multiple lines. |

---

# Typing Customization

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/topics/typing-customization/

Control Python annotation syntax, collection types, imports, and type mappings.

Options are grouped from shared CLI metadata and link back to their generated reference sections.

## Groups

| Group | Options | Description |
|-------|---------|-------------|
| [Imports](#imports) | 2 | Generated imports and type-checking import behavior. |
| [Collection Types](#collection-types) | 6 | Collection and tuple/set generation. |
| [Type Alias](#type-alias) | 3 | TypeAlias and root-model alias output. |
| [Type Mapping](#type-mapping) | 10 | Scalar, date/time, and custom type mapping. |
| [Type Syntax](#type-syntax) | 3 | Modern annotation syntax and Annotated usage. |

## Imports {#imports}

Generated imports and type-checking import behavior.

| Option | Description |
|--------|-------------|
| [`--disable-future-imports`](../typing-customization.md#disable-future-imports) | Prevent automatic addition of __future__ imports in generated code. |
| [`--import-overrides`](../typing-customization.md#import-overrides) | Override modules for generated imports by symbol name. |

## Collection Types {#collection-types}

Collection and tuple/set generation.

| Option | Description |
|--------|-------------|
| [`--no-use-standard-collections`](../typing-customization.md#no-use-standard-collections) | Use typing.Dict/List instead of built-in dict/list for container types. |
| [`--use-generic-container-types`](../typing-customization.md#use-generic-container-types) | Use generic container types (Sequence, Mapping) for type hinting. |
| [`--use-standard-collections`](../typing-customization.md#use-standard-collections) | Use built-in dict/list instead of typing.Dict/List. |
| [`--use-tuple-for-fixed-items`](../typing-customization.md#use-tuple-for-fixed-items) | Generate tuple types for arrays with items array syntax. |
| [`--use-tuple-for-fixed-length-arrays`](../typing-customization.md#use-tuple-for-fixed-length-arrays) | Generate tuple types for homogeneous fixed-length arrays. |
| [`--use-unique-items-as-set`](../typing-customization.md#use-unique-items-as-set) | Generate set types for arrays with uniqueItems constraint. |

## Type Alias {#type-alias}

TypeAlias and root-model alias output.

| Option | Description |
|--------|-------------|
| [`--use-root-model-type-alias`](../typing-customization.md#use-root-model-type-alias) | Generate RootModel as type alias format for better mypy support. |
| [`--use-type-alias`](../typing-customization.md#use-type-alias) | Use TypeAlias instead of root models for type definitions (experimental). |
| [`--use-type-alias-type`](../typing-customization.md#use-type-alias-type) | Use runtime TypeAliasType objects for aliases before Python 3.12 (experimental). |

## Type Mapping {#type-mapping}

Scalar, date/time, and custom type mapping.

| Option | Description |
|--------|-------------|
| [`--output-date-class`](../typing-customization.md#output-date-class) | Specify date class type for date schema fields. |
| [`--output-datetime-class`](../typing-customization.md#output-datetime-class) | Specify datetime class type for date-time schema fields. |
| [`--strict-types`](../typing-customization.md#strict-types) | Enable strict type validation for specified Python types. |
| [`--type-mappings`](../typing-customization.md#type-mappings) | Override default type mappings for schema formats. |
| [`--type-overrides`](../typing-customization.md#type-overrides) | Replace schema model types with custom Python types via JSON mapping. |
| [`--use-decimal-for-multiple-of`](../typing-customization.md#use-decimal-for-multiple-of) | Generate Decimal types for fields with multipleOf constraint. |
| [`--use-object-type`](../typing-customization.md#use-object-type) | Use object instead of Any for unspecified object and array values. |
| [`--use-pendulum`](../typing-customization.md#use-pendulum) | Use pendulum types for date, time, and duration fields. |
| [`--use-standard-primitive-types`](../typing-customization.md#use-standard-primitive-types) | Use Python standard library types for string formats instead of str. |
| [`--use-typed-nullable-map-values`](../typing-customization.md#use-typed-nullable-map-values) | Type the values of nullable maps as their schemas say instead of Any. |

## Type Syntax {#type-syntax}

Modern annotation syntax and Annotated usage.

| Option | Description |
|--------|-------------|
| [`--no-use-union-operator`](../typing-customization.md#no-use-union-operator) | Use Union\[X, Y\] / Optional\[X\] instead of X \| Y union operator. |
| [`--use-annotated`](../typing-customization.md#use-annotated) | Use typing.Annotated for Field() with constraints. |
| [`--use-union-operator`](../typing-customization.md#use-union-operator) | Use \| operator for Union types (PEP 604). |

---

# OpenAPI

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/topics/openapi/

Handle OpenAPI operation naming, path selection, scopes, and readOnly/writeOnly behavior.

Options are grouped from shared CLI metadata and link back to their generated reference sections.

## Groups

| Group | Options | Description |
|-------|---------|-------------|
| [OpenAPI Naming](#openapi-naming) | 2 | Operation and response model naming. |
| [OpenAPI Paths](#openapi-paths) | 2 | Path selection and path parameter output. |
| [OpenAPI Scopes](#openapi-scopes) | 1 | OpenAPI generation scopes. |
| [Read Only Write Only](#read-only-write-only) | 2 | readOnly/writeOnly model behavior. |

## OpenAPI Naming {#openapi-naming}

Operation and response model naming.

| Option | Description |
|--------|-------------|
| [`--use-operation-id-as-name`](../openapi-only-options.md#use-operation-id-as-name) | Use OpenAPI operationId as the generated function/class name. |
| [`--use-status-code-in-response-name`](../openapi-only-options.md#use-status-code-in-response-name) | Include HTTP status code in response model names. |

## OpenAPI Paths {#openapi-paths}

Path selection and path parameter output.

| Option | Description |
|--------|-------------|
| [`--include-path-parameters`](../openapi-only-options.md#include-path-parameters) | Include OpenAPI path parameters in generated parameter models. |
| [`--openapi-include-paths`](../openapi-only-options.md#openapi-include-paths) | Filter OpenAPI paths to include in model generation. |

## OpenAPI Scopes {#openapi-scopes}

OpenAPI generation scopes.

| Option | Description |
|--------|-------------|
| [`--openapi-scopes`](../openapi-only-options.md#openapi-scopes) | Specify OpenAPI scopes to generate (schemas, paths, parameters). |

## Read Only Write Only {#read-only-write-only}

readOnly/writeOnly model behavior.

| Option | Description |
|--------|-------------|
| [`--read-only-write-only-model-type`](../openapi-only-options.md#read-only-write-only-model-type) | Generate separate request and response models for readOnly/writeOnly fields. |
| [`--use-frozen-field`](../model-customization.md#use-frozen-field) | Generate frozen (immutable) field definitions for readOnly properties. |

---

# Quick Reference

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/quick-reference/

All CLI options in one page for easy **Ctrl+F** searching.

👆 Click any option to see detailed documentation with examples.

---

```text
datamodel-codegen [OPTIONS]
```

## 📂 All Options by Category

### 📁 Base Options

| Option | Description |
|--------|-------------|
| [`--emit-model-metadata`](base-options.md#emit-model-metadata) | Write a separate JSON map from source schema references to the final generated m... |
| [`--encoding`](base-options.md#encoding) | Specify character encoding for input and output files. |
| [`--external-ref-mapping`](base-options.md#external-ref-mapping) | Map external `$ref` files to Python packages. |
| [`--http-backend`](base-options.md#http-backend) | Select the HTTP client backend for remote schemas. |
| [`--input`](base-options.md#input) | Specify the input schema file path. |
| [`--input-file-type`](base-options.md#input-file-type) | Specify the input file type for code generation. |
| [`--input-model`](base-options.md#input-model) | Import a Python type or dict schema from a module or Python file. |
| [`--input-model-ref-strategy`](base-options.md#input-model-ref-strategy) | Strategy for referenced types when using --input-model. |
| [`--output`](base-options.md#output) | Specify the destination path for generated Python code. |
| [`--preset`](base-options.md#preset) | Apply an immutable built-in option preset. |
| [`--schema-version`](base-options.md#schema-version) | Schema version to use for parsing. |
| [`--schema-version-mode`](base-options.md#schema-version-mode) | Schema version validation mode. |
| [`--url`](base-options.md#url) | Fetch a schema from a URL with custom HTTP headers. |

### 🔧 Typing Customization

| Option | Description |
|--------|-------------|
| [`--allof-class-hierarchy`](typing-customization.md#allof-class-hierarchy) | Controls how allOf schemas are represented in the generated class hierarchy. `--... |
| [`--allof-merge-mode`](typing-customization.md#allof-merge-mode) | Merge constraints from root model references in allOf schemas. |
| [`--disable-future-imports`](typing-customization.md#disable-future-imports) | Prevent automatic addition of __future__ imports in generated code. |
| [`--enum-field-as-literal`](typing-customization.md#enum-field-as-literal) | Convert all enum fields to Literal types instead of Enum classes. |
| [`--enum-field-as-literal-map`](typing-customization.md#enum-field-as-literal-map) | Override enum/literal generation per-field via JSON mapping. |
| [`--ignore-enum-constraints`](typing-customization.md#ignore-enum-constraints) | Ignore enum constraints and use base string type instead of Enum classes. |
| [`--import-overrides`](typing-customization.md#import-overrides) | Override modules for generated imports by symbol name. |
| [`--no-use-closed-typed-dict`](typing-customization.md#no-use-closed-typed-dict) | Disable PEP 728 TypedDict closed/extra_items generation. |
| [`--no-use-specialized-enum`](typing-customization.md#no-use-specialized-enum) | Disable specialized Enum classes for Python 3.11+ code generation. |
| [`--no-use-standard-collections`](typing-customization.md#no-use-standard-collections) | Use typing.Dict/List instead of built-in dict/list for container types. |
| [`--no-use-union-operator`](typing-customization.md#no-use-union-operator) | Use Union[X, Y] / Optional[X] instead of X | Y union operator. |
| [`--output-date-class`](typing-customization.md#output-date-class) | Specify date class type for date schema fields. |
| [`--output-datetime-class`](typing-customization.md#output-datetime-class) | Specify datetime class type for date-time schema fields. |
| [`--strict-types`](typing-customization.md#strict-types) | Enable strict type validation for specified Python types. |
| [`--type-mappings`](typing-customization.md#type-mappings) | Override default type mappings for schema formats. |
| [`--type-overrides`](typing-customization.md#type-overrides) | Replace schema model types with custom Python types via JSON mapping. |
| [`--use-annotated`](typing-customization.md#use-annotated) | Use typing.Annotated for Field() with constraints. |
| [`--use-closed-typed-dict`](typing-customization.md#use-closed-typed-dict) | Generate TypedDict with PEP 728 closed/extra_items (default: enabled). |
| [`--use-decimal-for-multiple-of`](typing-customization.md#use-decimal-for-multiple-of) | Generate Decimal types for fields with multipleOf constraint. |
| [`--use-generic-container-types`](typing-customization.md#use-generic-container-types) | Use generic container types (Sequence, Mapping) for type hinting. |
| [`--use-non-positive-negative-number-constrained-types`](typing-customization.md#use-non-positive-negative-number-constrained-types) | Use NonPositive/NonNegative types for number constraints. |
| [`--use-object-type`](typing-customization.md#use-object-type) | Use object instead of Any for unspecified object and array values. |
| [`--use-pendulum`](typing-customization.md#use-pendulum) | Use pendulum types for date, time, and duration fields. |
| [`--use-root-model-type-alias`](typing-customization.md#use-root-model-type-alias) | Generate RootModel as type alias format for better mypy support. |
| [`--use-specialized-enum`](typing-customization.md#use-specialized-enum) | Generate StrEnum/IntEnum for string/integer enums (Python 3.11+). |
| [`--use-standard-collections`](typing-customization.md#use-standard-collections) | Use built-in dict/list instead of typing.Dict/List. |
| [`--use-standard-primitive-types`](typing-customization.md#use-standard-primitive-types) | Use Python standard library types for string formats instead of str. |
| [`--use-total-false-for-typed-dict`](typing-customization.md#use-total-false-for-typed-dict) | Generate TypedDict declarations with `total=False`. |
| [`--use-tuple-for-fixed-items`](typing-customization.md#use-tuple-for-fixed-items) | Generate tuple types for arrays with items array syntax. |
| [`--use-tuple-for-fixed-length-arrays`](typing-customization.md#use-tuple-for-fixed-length-arrays) | Generate tuple types for homogeneous fixed-length arrays. |
| [`--use-type-alias`](typing-customization.md#use-type-alias) | Use TypeAlias instead of root models for type definitions (experimental). |
| [`--use-type-alias-type`](typing-customization.md#use-type-alias-type) | Use runtime TypeAliasType objects for aliases before Python 3.12 (experimental). |
| [`--use-typed-nullable-map-values`](typing-customization.md#use-typed-nullable-map-values) | Type the values of nullable maps as their schemas say instead of Any. |
| [`--use-union-operator`](typing-customization.md#use-union-operator) | Use | operator for Union types (PEP 604). |
| [`--use-unique-items-as-set`](typing-customization.md#use-unique-items-as-set) | Generate set types for arrays with uniqueItems constraint. |

### 🏷️ Field Customization

| Option | Description |
|--------|-------------|
| [`--aliases`](field-customization.md#aliases) | Apply custom field and class name aliases via inline JSON or a JSON file path. |
| [`--capitalize-enum-members`](field-customization.md#capitalize-enum-members) | Capitalize enum member names to UPPER_CASE format. |
| [`--default-values`](field-customization.md#default-values) | Override field default values via inline JSON or a JSON file path. |
| [`--deserialize-default-values`](field-customization.md#deserialize-default-values) | Deserialize selected direct scalar field defaults into their generated Python ty... |
| [`--empty-enum-field-name`](field-customization.md#empty-enum-field-name) | Name for empty string enum field values. |
| [`--extra-fields`](field-customization.md#extra-fields) | Configure how generated models handle extra fields not defined in schema. |
| [`--field-constraints`](field-customization.md#field-constraints) | Generate Field() with validation constraints from schema. |
| [`--field-extra-keys`](field-customization.md#field-extra-keys) | Include specific extra keys in Field() definitions. |
| [`--field-extra-keys-without-x-prefix`](field-customization.md#field-extra-keys-without-x-prefix) | Include schema extension keys in Field() without requiring 'x-' prefix. |
| [`--field-include-all-keys`](field-customization.md#field-include-all-keys) | Include all schema keys in Field() json_schema_extra. |
| [`--field-type-collision-strategy`](field-customization.md#field-type-collision-strategy) | Rename type class instead of field when names collide (Pydantic v2 only). |
| [`--infer-union-variant-names`](field-customization.md#infer-union-variant-names) | Infer names for inline oneOf/anyOf object variants from literal fields. |
| [`--no-alias`](field-customization.md#no-alias) | Disable Field alias generation for non-Python-safe property names. |
| [`--no-deserialize-default-values`](field-customization.md#no-deserialize-default-values) | Keep serialized schema defaults instead of deserializing selected types. |
| [`--original-field-name-delimiter`](field-customization.md#original-field-name-delimiter) | Specify delimiter for original field names when using snake-case conversion. |
| [`--remove-special-field-name-prefix`](field-customization.md#remove-special-field-name-prefix) | Remove the special prefix from field names. |
| [`--serialization-aliases`](field-customization.md#serialization-aliases) | Apply custom Pydantic v2 serialization aliases via inline JSON or a JSON file pa... |
| [`--set-default-enum-member`](field-customization.md#set-default-enum-member) | Use the legacy flag for deserializing enum defaults. |
| [`--snake-case-field`](field-customization.md#snake-case-field) | Convert field names to snake_case format. |
| [`--special-field-name-prefix`](field-customization.md#special-field-name-prefix) | Prefix to add to special field names (like reserved keywords). |
| [`--use-attribute-docstrings`](field-customization.md#use-attribute-docstrings) | Generate field descriptions as attribute docstrings instead of Field description... |
| [`--use-enum-values-in-discriminator`](field-customization.md#use-enum-values-in-discriminator) | Use enum values in discriminator mappings for union types. |
| [`--use-field-description`](field-customization.md#use-field-description) | Include schema descriptions as Field docstrings. |
| [`--use-field-description-example`](field-customization.md#use-field-description-example) | Add field examples to docstrings. |
| [`--use-inline-field-description`](field-customization.md#use-inline-field-description) | Add field descriptions as inline comments. |
| [`--use-schema-description`](field-customization.md#use-schema-description) | Use schema description as class docstring. |
| [`--use-serialization-alias`](field-customization.md#use-serialization-alias) | Use serialization_alias instead of alias for field aliasing (Pydantic v2 only). |
| [`--use-single-line-docstring`](field-customization.md#use-single-line-docstring) | Emit short docstrings on a single line. |
| [`--use-title-as-name`](field-customization.md#use-title-as-name) | Use schema title as the generated class name. |

### 🏗️ Model Customization

| Option | Description |
|--------|-------------|
| [`--alias-generator`](model-customization.md#alias-generator) | Use a Pydantic v2 alias generator in model_config. |
| [`--allow-extra-fields`](model-customization.md#allow-extra-fields) | Allow extra fields in generated Pydantic models (extra='allow'). |
| [`--allow-leading-underscore-class-name`](model-customization.md#allow-leading-underscore-class-name) | Allow an explicitly specified root class name to start with an underscore. |
| [`--allow-population-by-field-name`](model-customization.md#allow-population-by-field-name) | Allow Pydantic model population by field name (not just alias). |
| [`--base-class`](model-customization.md#base-class) | Specify a custom base class for generated models. |
| [`--base-class-map`](model-customization.md#base-class-map) | Specify different base classes for specific models via JSON mapping. |
| [`--class-name`](model-customization.md#class-name) | Override the auto-generated class name with a custom name. |
| [`--class-name-affix-scope`](model-customization.md#class-name-affix-scope) | Control which classes receive the prefix/suffix. |
| [`--class-name-prefix`](model-customization.md#class-name-prefix) | Add a prefix to all generated class names. |
| [`--class-name-suffix`](model-customization.md#class-name-suffix) | Add a suffix to all generated class names. |
| [`--collapse-reuse-models`](model-customization.md#collapse-reuse-models) | Collapse duplicate models by replacing references instead of inheritance. |
| [`--collapse-root-models`](model-customization.md#collapse-root-models) | Inline root model definitions instead of creating separate wrapper classes. |
| [`--collapse-root-models-name-strategy`](model-customization.md#collapse-root-models-name-strategy) | Select which name to keep when collapsing root models with object references. |
| [`--dataclass-arguments`](model-customization.md#dataclass-arguments) | Customize dataclass decorator arguments via JSON dictionary. |
| [`--duplicate-name-suffix`](model-customization.md#duplicate-name-suffix) | Customize suffix for duplicate model names. |
| [`--enable-faux-immutability`](model-customization.md#enable-faux-immutability) | Enable faux immutability in Pydantic models (frozen=True). |
| [`--force-optional`](model-customization.md#force-optional) | Force all fields to be Optional regardless of required status. |
| [`--frozen-dataclasses`](model-customization.md#frozen-dataclasses) | Generate frozen dataclasses with optional keyword-only fields. |
| [`--keep-model-order`](model-customization.md#keep-model-order) | Keep generated model order deterministic while respecting dependency constraints... |
| [`--keyword-only`](model-customization.md#keyword-only) | Generate dataclasses with keyword-only fields (Python 3.10+). |
| [`--model-extra-keys`](model-customization.md#model-extra-keys) | Add model-level schema extensions to ConfigDict json_schema_extra. |
| [`--model-extra-keys-without-x-prefix`](model-customization.md#model-extra-keys-without-x-prefix) | Strip x- prefix from model-level schema extensions and add to ConfigDict json_sc... |
| [`--model-name-map`](model-customization.md#model-name-map) | Rename generated model classes from a JSON mapping. |
| [`--naming-strategy`](model-customization.md#naming-strategy) | Use parent-prefixed naming strategy for duplicate model names. |
| [`--output-model-type`](model-customization.md#output-model-type) | Select the output model type (Pydantic v2, Pydantic v2 dataclass, dataclasses, T... |
| [`--parent-scoped-naming`](model-customization.md#parent-scoped-naming) | Namespace models by their parent scope to avoid naming conflicts. |
| [`--reuse-model`](model-customization.md#reuse-model) | Reuse identical model definitions instead of generating duplicates. |
| [`--reuse-scope`](model-customization.md#reuse-scope) | Scope for model reuse detection (root or tree). |
| [`--skip-root-model`](model-customization.md#skip-root-model) | Skip generation of root model when schema contains nested definitions. |
| [`--strict-nullable`](model-customization.md#strict-nullable) | Treat default field as a non-nullable field. |
| [`--strip-default-none`](model-customization.md#strip-default-none) | Remove fields with None as default value from generated models. |
| [`--target-pydantic-version`](model-customization.md#target-pydantic-version) | Target Pydantic version for generated code compatibility. |
| [`--target-python-version`](model-customization.md#target-python-version) | Target Python version for generated code syntax and imports. |
| [`--union-mode`](model-customization.md#union-mode) | Union mode for combining anyOf/oneOf schemas (smart or left_to_right). |
| [`--use-default`](model-customization.md#use-default) | Use default values from schema in generated models. |
| [`--use-default-factory-for-optional-nested-models`](model-customization.md#use-default-factory-for-optional-nested-models) | Generate default_factory for optional nested model fields. |
| [`--use-default-kwarg`](model-customization.md#use-default-kwarg) | Use default= keyword argument instead of positional argument for fields with def... |
| [`--use-frozen-field`](model-customization.md#use-frozen-field) | Generate frozen (immutable) field definitions for readOnly properties. |
| [`--use-generic-base-class`](model-customization.md#use-generic-base-class) | Generate a shared base class with model configuration to avoid repetition (DRY). |
| [`--use-missing-sentinel`](model-customization.md#use-missing-sentinel) | Use Pydantic's MISSING sentinel for unset optional BaseModel or dataclass fields... |
| [`--use-msgspec-nullable-enum-alias`](model-customization.md#use-msgspec-nullable-enum-alias) | Write a msgspec.Struct enum that lists null as an Enum and a nullable alias. |
| [`--use-msgspec-tagged-unions`](model-customization.md#use-msgspec-tagged-unions) | Write a msgspec.Struct discriminated union as tagged structs as a whole. |
| [`--use-one-literal-as-default`](model-customization.md#use-one-literal-as-default) | Use single literal value as default when enum has only one option. |
| [`--use-root-model-sequence-interface`](model-customization.md#use-root-model-sequence-interface) | Make non-null sequence-like Pydantic v2 RootModel classes implement collections.... |
| [`--use-serialize-as-any`](model-customization.md#use-serialize-as-any) | Wrap fields with subtypes in Pydantic's SerializeAsAny. |
| [`--use-subclass-enum`](model-customization.md#use-subclass-enum) | Generate typed Enum subclasses for enums with specific field types. |

### 🎨 Template Customization

| Option | Description |
|--------|-------------|
| [`--additional-imports`](template-customization.md#additional-imports) | Add custom imports to generated output files. |
| [`--class-decorators`](template-customization.md#class-decorators) | Add custom decorators to generated model classes. |
| [`--custom-file-header`](template-customization.md#custom-file-header) | Add custom header text to the generated file. |
| [`--custom-file-header-mode`](template-customization.md#custom-file-header-mode) | Choose how a custom file header combines with generated provenance. |
| [`--custom-file-header-path`](template-customization.md#custom-file-header-path) | Add custom header content from file to generated code. |
| [`--custom-formatters`](template-customization.md#custom-formatters) | Apply custom Python code formatters to generated output. |
| [`--custom-formatters-kwargs`](template-customization.md#custom-formatters-kwargs) | Pass custom arguments to custom formatters via inline JSON or a JSON file path. |
| [`--custom-template-dir`](template-customization.md#custom-template-dir) | Use custom Jinja2 templates for model generation. |
| [`--disable-appending-item-suffix`](template-customization.md#disable-appending-item-suffix) | Disable appending 'Item' suffix to array item types. |
| [`--disable-timestamp`](template-customization.md#disable-timestamp) | Disable timestamp in generated file header for reproducible output. |
| [`--enable-command-header`](template-customization.md#enable-command-header) | Include command-line options in file header for reproducibility. |
| [`--enable-generated-header-marker`](template-customization.md#enable-generated-header-marker) | Include the @generated marker in file header for generated-code tooling. |
| [`--enable-version-header`](template-customization.md#enable-version-header) | Include tool version information in file header. |
| [`--extra-template-data`](template-customization.md#extra-template-data) | Pass custom template variables via inline JSON or a JSON file path. |
| [`--formatters`](template-customization.md#formatters) | Specify code formatters to apply to generated output. |
| [`--generate-schema-validators`](template-customization.md#generate-schema-validators) | Generate experimental Pydantic v2 model validators for JSON Schema runtime rules... |
| [`--no-treat-dot-as-module`](template-customization.md#no-treat-dot-as-module) | Keep dots in schema names as underscores for flat output. |
| [`--no-use-type-checking-imports`](template-customization.md#no-use-type-checking-imports) | Keep generated model imports available at runtime when using Ruff fixes. |
| [`--schema-validator-base-class-name`](template-customization.md#schema-validator-base-class-name) | Set the generated shared Pydantic v2 schema runtime validator base class name. |
| [`--schema-validator-type`](template-customization.md#schema-validator-type) | Select the schema-derived runtime validator backend. |
| [`--strict-dotted-module-names`](template-customization.md#strict-dotted-module-names) | Require canonical Python identifiers when inferring dotted module paths. |
| [`--treat-dot-as-module`](template-customization.md#treat-dot-as-module) | Treat dots in schema names as module separators. |
| [`--use-double-quotes`](template-customization.md#use-double-quotes) | Use double quotes for string literals in generated code. |
| [`--use-exact-imports`](template-customization.md#use-exact-imports) | Import exact types instead of modules. |
| [`--use-type-checking-imports`](template-customization.md#use-type-checking-imports) | Allow Ruff to move typing-only imports into TYPE_CHECKING blocks. |
| [`--validators`](template-customization.md#validators) | Add custom field validators to generated Pydantic v2 models. |
| [`--wrap-string-literal`](template-customization.md#wrap-string-literal) | Wrap long string literals across multiple lines. |

### 📘 OpenAPI-only Options

| Option | Description |
|--------|-------------|
| [`--include-path-parameters`](openapi-only-options.md#include-path-parameters) | Include OpenAPI path parameters in generated parameter models. |
| [`--openapi-include-info-version`](openapi-only-options.md#openapi-include-info-version) | Emit OpenAPI info.version as a generated constant. |
| [`--openapi-include-paths`](openapi-only-options.md#openapi-include-paths) | Filter OpenAPI paths to include in model generation. |
| [`--openapi-scopes`](openapi-only-options.md#openapi-scopes) | Specify OpenAPI scopes to generate (schemas, paths, parameters). |
| [`--read-only-write-only-model-type`](openapi-only-options.md#read-only-write-only-model-type) | Generate separate request and response models for readOnly/writeOnly fields. |
| [`--use-operation-id-as-name`](openapi-only-options.md#use-operation-id-as-name) | Use OpenAPI operationId as the generated function/class name. |
| [`--use-status-code-in-response-name`](openapi-only-options.md#use-status-code-in-response-name) | Include HTTP status code in response model names. |
| [`--validation`](openapi-only-options.md#validation) | Enable validation constraints (deprecated, use --field-constraints). |

### 📋 GraphQL-only Options

| Option | Description |
|--------|-------------|
| [`--graphql-no-typename`](graphql-only-options.md#graphql-no-typename) | Exclude __typename field from generated GraphQL models. |

### ⚙️ General Options

| Option | Description |
|--------|-------------|
| [`--all-exports-collision-strategy`](general-options.md#all-exports-collision-strategy) | Handle name collisions when exporting recursive module hierarchies. |
| [`--all-exports-scope`](general-options.md#all-exports-scope) | Generate __all__ exports for child modules in __init__.py files. |
| [`--allow-private-network`](general-options.md#allow-private-network) | Allow HTTP requests to private network schema endpoints. |
| [`--allow-remote-refs`](general-options.md#allow-remote-refs) | Enable fetching of `$ref` targets over HTTP/HTTPS. |
| [`--check`](general-options.md#check) | Verify generated code matches existing output without modifying files. |
| [`--diff-against`](general-options.md#diff-against) | Compare generated code from a baseline input with the current schema without wri... |
| [`--disable-warnings`](general-options.md#disable-warnings) | Suppress warning messages during code generation. |
| [`--fail-on-multi-module-stdout`](general-options.md#fail-on-multi-module-stdout) | Fail instead of concatenating multiple modules in text stdout. |
| [`--generate-cli-command`](general-options.md#generate-cli-command) | Generate CLI command from pyproject.toml configuration. |
| [`--generate-pyproject-config`](general-options.md#generate-pyproject-config) | Generate pyproject.toml configuration from CLI arguments. |
| [`--http-headers`](general-options.md#http-headers) | Fetch a schema from a URL with custom HTTP headers. |
| [`--http-ignore-tls`](general-options.md#http-ignore-tls) | Disable TLS certificate verification for HTTPS requests. |
| [`--http-local-ref-path`](general-options.md#http-local-ref-path) | Resolve HTTP references from local schema files. |
| [`--http-query-parameters`](general-options.md#http-query-parameters) | Add query parameters to HTTP requests for remote schemas. |
| [`--http-timeout`](general-options.md#http-timeout) | Set timeout for HTTP requests to remote hosts. |
| [`--ignore-pyproject`](general-options.md#ignore-pyproject) | Ignore pyproject.toml configuration file. |
| [`--locked`](general-options.md#locked) | Require an existing remote lock and validate each fetched resource against it (e... |
| [`--lockfile`](general-options.md#lockfile) | Select the remote reference integrity lock file (experimental). |
| [`--module-split-mode`](general-options.md#module-split-mode) | Split generated models into separate files, one per model class. |
| [`--shared-module-name`](general-options.md#shared-module-name) | Customize the name of the shared module for deduplicated models. |
| [`--strict-refs`](general-options.md#strict-refs) | Treat unresolved local `$ref` JSON pointers as errors. |
| [`--update-lock`](general-options.md#update-lock) | Create or atomically update the selected remote lock after generation (experimen... |
| [`--watch`](general-options.md#watch) | Watch input file(s) for changes and regenerate output automatically. |
| [`--watch-delay`](general-options.md#watch-delay) | Set debounce delay in seconds for watch mode. |

### 🚀 Target Generation Options

| Option | Description |
|--------|-------------|
| [`--client-body-arguments`](target-generation-options.md#client-body-arguments) | Choose how operation methods take request bodies (experimental). |
| [`--client-default-base-url`](target-generation-options.md#client-default-base-url) | Set the server URL of operations that declare no servers (experimental). |
| [`--client-model-package`](target-generation-options.md#client-model-package) | Name the import path of the models the client package imports (experimental). |
| [`--client-operations`](target-generation-options.md#client-operations) | Set the client settings of single operations (experimental). |
| [`--client-output`](target-generation-options.md#client-output) | Write the client package to this directory (experimental). |
| [`--client-package`](target-generation-options.md#client-package) | Name the import path of the client package (experimental). |
| [`--client-protocols`](target-generation-options.md#client-protocols) | Declare the protocol helpers of the client package (experimental). |
| [`--client-resource-names`](target-generation-options.md#client-resource-names) | Name the resources of tags (experimental). |
| [`--client-server-base-url`](target-generation-options.md#client-server-base-url) | Resolve relative server URLs against this base URL (experimental). |
| [`--client-signature-style`](target-generation-options.md#client-signature-style) | Declare the arguments of the operation methods (experimental). |
| [`--generate-client`](target-generation-options.md#generate-client) | Generate an HTTPX2 client package for the models (experimental). |
| [`--generate-server`](target-generation-options.md#generate-server) | Generate a FastAPI server package for the models (experimental). |
| [`--server-body-mode`](target-generation-options.md#server-body-mode) | Choose how service methods receive request bodies (experimental). |
| [`--server-body-modes`](target-generation-options.md#server-body-modes) | Set the body mode of single operations (experimental). |
| [`--server-handler-mode`](target-generation-options.md#server-handler-mode) | Declare the service methods as plain or coroutine functions (experimental). |
| [`--server-handler-modes`](target-generation-options.md#server-handler-modes) | Set the handler mode of single operations (experimental). |
| [`--server-include-request`](target-generation-options.md#server-include-request) | Pass the Starlette Request to every service method (experimental). |
| [`--server-layout`](target-generation-options.md#server-layout) | Choose how the server package lays out its routes (experimental). |
| [`--server-model-package`](target-generation-options.md#server-model-package) | Name the import path of the models the server package imports (experimental). |
| [`--server-operation-names`](target-generation-options.md#server-operation-names) | Name the service methods of single operations (experimental). |
| [`--server-output`](target-generation-options.md#server-output) | Write the server package to this directory (experimental). |
| [`--server-package`](target-generation-options.md#server-package) | Name the import path of the server package (experimental). |
| [`--server-parameter-names`](target-generation-options.md#server-parameter-names) | Name the method arguments of single operations (experimental). |
| [`--server-primary-responses`](target-generation-options.md#server-primary-responses) | Choose the response a bare return value of an operation takes (experimental). |
| [`--server-router-names`](target-generation-options.md#server-router-names) | Name router groups (experimental). |

### 📝 Utility Options

| Option | Description |
|--------|-------------|
| [`--all-jobs`](utility-options.md#all-jobs) | Run every named generation job from pyproject.toml (experimental) |
| [`--debug`](utility-options.md#debug) | Show debug messages during code generation |
| [`--generate-prompt`](utility-options.md#generate-prompt) | Generate a prompt for consulting LLMs about CLI options |
| [`--help`](utility-options.md#help) | Show help message and exit |
| [`--install-skill`](utility-options.md#install-skill) | Install the bundled Agent Skill (experimental) |
| [`--job`](utility-options.md#job) | Run a named generation job from pyproject.toml (experimental) |
| [`--list-deprecations`](utility-options.md#list-deprecations) | List registered deprecations and scheduled breaking changes |
| [`--list-experimental`](utility-options.md#list-experimental) | List registered experimental features |
| [`--no-color`](utility-options.md#no-color) | Disable colorized output |
| [`--output-format`](utility-options.md#output-format) | Choose the command output format |
| [`--output-format-json-schema`](utility-options.md#output-format-json-schema) | Output JSON Schema for structured command output or JSON configuration |
| [`--overwrite-skill`](utility-options.md#overwrite-skill) | Replace an existing Agent Skill installation |
| [`--profile`](utility-options.md#profile) | Use a named profile from pyproject.toml |
| [`--skill-scope`](utility-options.md#skill-scope) | Choose an Agent Skill installation scope |
| [`--version`](utility-options.md#version) | Show program version and exit |

---

## 🔤 Alphabetical Index

All options sorted alphabetically:

- [`--additional-imports`](template-customization.md#additional-imports) - Add custom imports to generated output files.
- [`--alias-generator`](model-customization.md#alias-generator) - Use a Pydantic v2 alias generator in model_config.
- [`--aliases`](field-customization.md#aliases) - Apply custom field and class name aliases via inline JSON or...
- [`--all-exports-collision-strategy`](general-options.md#all-exports-collision-strategy) - Handle name collisions when exporting recursive module hiera...
- [`--all-exports-scope`](general-options.md#all-exports-scope) - Generate __all__ exports for child modules in __init__.py fi...
- [`--all-jobs`](utility-options.md#all-jobs) - Run every named generation job from pyproject.toml (experimental)
- [`--allof-class-hierarchy`](typing-customization.md#allof-class-hierarchy) - Controls how allOf schemas are represented in the generated ...
- [`--allof-merge-mode`](typing-customization.md#allof-merge-mode) - Merge constraints from root model references in allOf schema...
- [`--allow-extra-fields`](model-customization.md#allow-extra-fields) - Allow extra fields in generated Pydantic models (extra='allo...
- [`--allow-leading-underscore-class-name`](model-customization.md#allow-leading-underscore-class-name) - Allow an explicitly specified root class name to start with ...
- [`--allow-population-by-field-name`](model-customization.md#allow-population-by-field-name) - Allow Pydantic model population by field name (not just alia...
- [`--allow-private-network`](general-options.md#allow-private-network) - Allow HTTP requests to private network schema endpoints.
- [`--allow-remote-refs`](general-options.md#allow-remote-refs) - Enable fetching of `$ref` targets over HTTP/HTTPS.
- [`--base-class`](model-customization.md#base-class) - Specify a custom base class for generated models.
- [`--base-class-map`](model-customization.md#base-class-map) - Specify different base classes for specific models via JSON ...
- [`--capitalize-enum-members`](field-customization.md#capitalize-enum-members) - Capitalize enum member names to UPPER_CASE format.
- [`--check`](general-options.md#check) - Verify generated code matches existing output without modify...
- [`--class-decorators`](template-customization.md#class-decorators) - Add custom decorators to generated model classes.
- [`--class-name`](model-customization.md#class-name) - Override the auto-generated class name with a custom name.
- [`--class-name-affix-scope`](model-customization.md#class-name-affix-scope) - Control which classes receive the prefix/suffix.
- [`--class-name-prefix`](model-customization.md#class-name-prefix) - Add a prefix to all generated class names.
- [`--class-name-suffix`](model-customization.md#class-name-suffix) - Add a suffix to all generated class names.
- [`--client-body-arguments`](target-generation-options.md#client-body-arguments) - Choose how operation methods take request bodies (experiment...
- [`--client-default-base-url`](target-generation-options.md#client-default-base-url) - Set the server URL of operations that declare no servers (ex...
- [`--client-model-package`](target-generation-options.md#client-model-package) - Name the import path of the models the client package import...
- [`--client-operations`](target-generation-options.md#client-operations) - Set the client settings of single operations (experimental).
- [`--client-output`](target-generation-options.md#client-output) - Write the client package to this directory (experimental).
- [`--client-package`](target-generation-options.md#client-package) - Name the import path of the client package (experimental).
- [`--client-protocols`](target-generation-options.md#client-protocols) - Declare the protocol helpers of the client package (experime...
- [`--client-resource-names`](target-generation-options.md#client-resource-names) - Name the resources of tags (experimental).
- [`--client-server-base-url`](target-generation-options.md#client-server-base-url) - Resolve relative server URLs against this base URL (experime...
- [`--client-signature-style`](target-generation-options.md#client-signature-style) - Declare the arguments of the operation methods (experimental...
- [`--collapse-reuse-models`](model-customization.md#collapse-reuse-models) - Collapse duplicate models by replacing references instead of...
- [`--collapse-root-models`](model-customization.md#collapse-root-models) - Inline root model definitions instead of creating separate w...
- [`--collapse-root-models-name-strategy`](model-customization.md#collapse-root-models-name-strategy) - Select which name to keep when collapsing root models with o...
- [`--custom-file-header`](template-customization.md#custom-file-header) - Add custom header text to the generated file.
- [`--custom-file-header-mode`](template-customization.md#custom-file-header-mode) - Choose how a custom file header combines with generated prov...
- [`--custom-file-header-path`](template-customization.md#custom-file-header-path) - Add custom header content from file to generated code.
- [`--custom-formatters`](template-customization.md#custom-formatters) - Apply custom Python code formatters to generated output.
- [`--custom-formatters-kwargs`](template-customization.md#custom-formatters-kwargs) - Pass custom arguments to custom formatters via inline JSON o...
- [`--custom-template-dir`](template-customization.md#custom-template-dir) - Use custom Jinja2 templates for model generation.
- [`--dataclass-arguments`](model-customization.md#dataclass-arguments) - Customize dataclass decorator arguments via JSON dictionary.
- [`--debug`](utility-options.md#debug) - Show debug messages during code generation
- [`--default-values`](field-customization.md#default-values) - Override field default values via inline JSON or a JSON file...
- [`--deserialize-default-values`](field-customization.md#deserialize-default-values) - Deserialize selected direct scalar field defaults into their...
- [`--diff-against`](general-options.md#diff-against) - Compare generated code from a baseline input with the curren...
- [`--disable-appending-item-suffix`](template-customization.md#disable-appending-item-suffix) - Disable appending 'Item' suffix to array item types.
- [`--disable-future-imports`](typing-customization.md#disable-future-imports) - Prevent automatic addition of __future__ imports in generate...
- [`--disable-timestamp`](template-customization.md#disable-timestamp) - Disable timestamp in generated file header for reproducible ...
- [`--disable-warnings`](general-options.md#disable-warnings) - Suppress warning messages during code generation.
- [`--duplicate-name-suffix`](model-customization.md#duplicate-name-suffix) - Customize suffix for duplicate model names.
- [`--emit-model-metadata`](base-options.md#emit-model-metadata) - Write a separate JSON map from source schema references to t...
- [`--empty-enum-field-name`](field-customization.md#empty-enum-field-name) - Name for empty string enum field values.
- [`--enable-command-header`](template-customization.md#enable-command-header) - Include command-line options in file header for reproducibil...
- [`--enable-faux-immutability`](model-customization.md#enable-faux-immutability) - Enable faux immutability in Pydantic models (frozen=True).
- [`--enable-generated-header-marker`](template-customization.md#enable-generated-header-marker) - Include the @generated marker in file header for generated-c...
- [`--enable-version-header`](template-customization.md#enable-version-header) - Include tool version information in file header.
- [`--encoding`](base-options.md#encoding) - Specify character encoding for input and output files.
- [`--enum-field-as-literal`](typing-customization.md#enum-field-as-literal) - Convert all enum fields to Literal types instead of Enum cla...
- [`--enum-field-as-literal-map`](typing-customization.md#enum-field-as-literal-map) - Override enum/literal generation per-field via JSON mapping.
- [`--external-ref-mapping`](base-options.md#external-ref-mapping) - Map external `$ref` files to Python packages.
- [`--extra-fields`](field-customization.md#extra-fields) - Configure how generated models handle extra fields not defin...
- [`--extra-template-data`](template-customization.md#extra-template-data) - Pass custom template variables via inline JSON or a JSON fil...
- [`--fail-on-multi-module-stdout`](general-options.md#fail-on-multi-module-stdout) - Fail instead of concatenating multiple modules in text stdou...
- [`--field-constraints`](field-customization.md#field-constraints) - Generate Field() with validation constraints from schema.
- [`--field-extra-keys`](field-customization.md#field-extra-keys) - Include specific extra keys in Field() definitions.
- [`--field-extra-keys-without-x-prefix`](field-customization.md#field-extra-keys-without-x-prefix) - Include schema extension keys in Field() without requiring '...
- [`--field-include-all-keys`](field-customization.md#field-include-all-keys) - Include all schema keys in Field() json_schema_extra.
- [`--field-type-collision-strategy`](field-customization.md#field-type-collision-strategy) - Rename type class instead of field when names collide (Pydan...
- [`--force-optional`](model-customization.md#force-optional) - Force all fields to be Optional regardless of required statu...
- [`--formatters`](template-customization.md#formatters) - Specify code formatters to apply to generated output.
- [`--frozen-dataclasses`](model-customization.md#frozen-dataclasses) - Generate frozen dataclasses with optional keyword-only field...
- [`--generate-cli-command`](general-options.md#generate-cli-command) - Generate CLI command from pyproject.toml configuration.
- [`--generate-client`](target-generation-options.md#generate-client) - Generate an HTTPX2 client package for the models (experiment...
- [`--generate-prompt`](utility-options.md#generate-prompt) - Generate a prompt for consulting LLMs about CLI options
- [`--generate-pyproject-config`](general-options.md#generate-pyproject-config) - Generate pyproject.toml configuration from CLI arguments.
- [`--generate-schema-validators`](template-customization.md#generate-schema-validators) - Generate experimental Pydantic v2 model validators for JSON ...
- [`--generate-server`](target-generation-options.md#generate-server) - Generate a FastAPI server package for the models (experiment...
- [`--graphql-no-typename`](graphql-only-options.md#graphql-no-typename) - Exclude __typename field from generated GraphQL models.
- [`--help`](utility-options.md#help) - Show help message and exit
- [`--http-backend`](base-options.md#http-backend) - Select the HTTP client backend for remote schemas.
- [`--http-headers`](general-options.md#http-headers) - Fetch a schema from a URL with custom HTTP headers.
- [`--http-ignore-tls`](general-options.md#http-ignore-tls) - Disable TLS certificate verification for HTTPS requests.
- [`--http-local-ref-path`](general-options.md#http-local-ref-path) - Resolve HTTP references from local schema files.
- [`--http-query-parameters`](general-options.md#http-query-parameters) - Add query parameters to HTTP requests for remote schemas.
- [`--http-timeout`](general-options.md#http-timeout) - Set timeout for HTTP requests to remote hosts.
- [`--ignore-enum-constraints`](typing-customization.md#ignore-enum-constraints) - Ignore enum constraints and use base string type instead of ...
- [`--ignore-pyproject`](general-options.md#ignore-pyproject) - Ignore pyproject.toml configuration file.
- [`--import-overrides`](typing-customization.md#import-overrides) - Override modules for generated imports by symbol name.
- [`--include-path-parameters`](openapi-only-options.md#include-path-parameters) - Include OpenAPI path parameters in generated parameter model...
- [`--infer-union-variant-names`](field-customization.md#infer-union-variant-names) - Infer names for inline oneOf/anyOf object variants from lite...
- [`--input`](base-options.md#input) - Specify the input schema file path.
- [`--input-file-type`](base-options.md#input-file-type) - Specify the input file type for code generation.
- [`--input-model`](base-options.md#input-model) - Import a Python type or dict schema from a module or Python ...
- [`--input-model-ref-strategy`](base-options.md#input-model-ref-strategy) - Strategy for referenced types when using --input-model.
- [`--install-skill`](utility-options.md#install-skill) - Install the bundled Agent Skill (experimental)
- [`--job`](utility-options.md#job) - Run a named generation job from pyproject.toml (experimental)
- [`--keep-model-order`](model-customization.md#keep-model-order) - Keep generated model order deterministic while respecting de...
- [`--keyword-only`](model-customization.md#keyword-only) - Generate dataclasses with keyword-only fields (Python 3.10+)...
- [`--list-deprecations`](utility-options.md#list-deprecations) - List registered deprecations and scheduled breaking changes
- [`--list-experimental`](utility-options.md#list-experimental) - List registered experimental features
- [`--locked`](general-options.md#locked) - Require an existing remote lock and validate each fetched re...
- [`--lockfile`](general-options.md#lockfile) - Select the remote reference integrity lock file (experimenta...
- [`--model-extra-keys`](model-customization.md#model-extra-keys) - Add model-level schema extensions to ConfigDict json_schema_...
- [`--model-extra-keys-without-x-prefix`](model-customization.md#model-extra-keys-without-x-prefix) - Strip x- prefix from model-level schema extensions and add t...
- [`--model-name-map`](model-customization.md#model-name-map) - Rename generated model classes from a JSON mapping.
- [`--module-split-mode`](general-options.md#module-split-mode) - Split generated models into separate files, one per model cl...
- [`--naming-strategy`](model-customization.md#naming-strategy) - Use parent-prefixed naming strategy for duplicate model name...
- [`--no-alias`](field-customization.md#no-alias) - Disable Field alias generation for non-Python-safe property ...
- [`--no-color`](utility-options.md#no-color) - Disable colorized output
- [`--no-deserialize-default-values`](field-customization.md#no-deserialize-default-values) - Keep serialized schema defaults instead of deserializing sel...
- [`--no-treat-dot-as-module`](template-customization.md#no-treat-dot-as-module) - Keep dots in schema names as underscores for flat output.
- [`--no-use-closed-typed-dict`](typing-customization.md#no-use-closed-typed-dict) - Disable PEP 728 TypedDict closed/extra_items generation.
- [`--no-use-specialized-enum`](typing-customization.md#no-use-specialized-enum) - Disable specialized Enum classes for Python 3.11+ code gener...
- [`--no-use-standard-collections`](typing-customization.md#no-use-standard-collections) - Use typing.Dict/List instead of built-in dict/list for conta...
- [`--no-use-type-checking-imports`](template-customization.md#no-use-type-checking-imports) - Keep generated model imports available at runtime when using...
- [`--no-use-union-operator`](typing-customization.md#no-use-union-operator) - Use Union[X, Y] / Optional[X] instead of X | Y union operato...
- [`--openapi-include-info-version`](openapi-only-options.md#openapi-include-info-version) - Emit OpenAPI info.version as a generated constant.
- [`--openapi-include-paths`](openapi-only-options.md#openapi-include-paths) - Filter OpenAPI paths to include in model generation.
- [`--openapi-scopes`](openapi-only-options.md#openapi-scopes) - Specify OpenAPI scopes to generate (schemas, paths, paramete...
- [`--original-field-name-delimiter`](field-customization.md#original-field-name-delimiter) - Specify delimiter for original field names when using snake-...
- [`--output`](base-options.md#output) - Specify the destination path for generated Python code.
- [`--output-date-class`](typing-customization.md#output-date-class) - Specify date class type for date schema fields.
- [`--output-datetime-class`](typing-customization.md#output-datetime-class) - Specify datetime class type for date-time schema fields.
- [`--output-format`](utility-options.md#output-format) - Choose the command output format
- [`--output-format-json-schema`](utility-options.md#output-format-json-schema) - Output JSON Schema for structured command output or JSON configuration
- [`--output-model-type`](model-customization.md#output-model-type) - Select the output model type (Pydantic v2, Pydantic v2 datac...
- [`--overwrite-skill`](utility-options.md#overwrite-skill) - Replace an existing Agent Skill installation
- [`--parent-scoped-naming`](model-customization.md#parent-scoped-naming) - Namespace models by their parent scope to avoid naming confl...
- [`--preset`](base-options.md#preset) - Apply an immutable built-in option preset.
- [`--profile`](utility-options.md#profile) - Use a named profile from pyproject.toml
- [`--read-only-write-only-model-type`](openapi-only-options.md#read-only-write-only-model-type) - Generate separate request and response models for readOnly/w...
- [`--remove-special-field-name-prefix`](field-customization.md#remove-special-field-name-prefix) - Remove the special prefix from field names.
- [`--reuse-model`](model-customization.md#reuse-model) - Reuse identical model definitions instead of generating dupl...
- [`--reuse-scope`](model-customization.md#reuse-scope) - Scope for model reuse detection (root or tree).
- [`--schema-validator-base-class-name`](template-customization.md#schema-validator-base-class-name) - Set the generated shared Pydantic v2 schema runtime validato...
- [`--schema-validator-type`](template-customization.md#schema-validator-type) - Select the schema-derived runtime validator backend.
- [`--schema-version`](base-options.md#schema-version) - Schema version to use for parsing.
- [`--schema-version-mode`](base-options.md#schema-version-mode) - Schema version validation mode.
- [`--serialization-aliases`](field-customization.md#serialization-aliases) - Apply custom Pydantic v2 serialization aliases via inline JS...
- [`--server-body-mode`](target-generation-options.md#server-body-mode) - Choose how service methods receive request bodies (experimen...
- [`--server-body-modes`](target-generation-options.md#server-body-modes) - Set the body mode of single operations (experimental).
- [`--server-handler-mode`](target-generation-options.md#server-handler-mode) - Declare the service methods as plain or coroutine functions ...
- [`--server-handler-modes`](target-generation-options.md#server-handler-modes) - Set the handler mode of single operations (experimental).
- [`--server-include-request`](target-generation-options.md#server-include-request) - Pass the Starlette Request to every service method (experime...
- [`--server-layout`](target-generation-options.md#server-layout) - Choose how the server package lays out its routes (experimen...
- [`--server-model-package`](target-generation-options.md#server-model-package) - Name the import path of the models the server package import...
- [`--server-operation-names`](target-generation-options.md#server-operation-names) - Name the service methods of single operations (experimental)...
- [`--server-output`](target-generation-options.md#server-output) - Write the server package to this directory (experimental).
- [`--server-package`](target-generation-options.md#server-package) - Name the import path of the server package (experimental).
- [`--server-parameter-names`](target-generation-options.md#server-parameter-names) - Name the method arguments of single operations (experimental...
- [`--server-primary-responses`](target-generation-options.md#server-primary-responses) - Choose the response a bare return value of an operation take...
- [`--server-router-names`](target-generation-options.md#server-router-names) - Name router groups (experimental).
- [`--set-default-enum-member`](field-customization.md#set-default-enum-member) - Use the legacy flag for deserializing enum defaults.
- [`--shared-module-name`](general-options.md#shared-module-name) - Customize the name of the shared module for deduplicated mod...
- [`--skill-scope`](utility-options.md#skill-scope) - Choose an Agent Skill installation scope
- [`--skip-root-model`](model-customization.md#skip-root-model) - Skip generation of root model when schema contains nested de...
- [`--snake-case-field`](field-customization.md#snake-case-field) - Convert field names to snake_case format.
- [`--special-field-name-prefix`](field-customization.md#special-field-name-prefix) - Prefix to add to special field names (like reserved keywords...
- [`--strict-dotted-module-names`](template-customization.md#strict-dotted-module-names) - Require canonical Python identifiers when inferring dotted m...
- [`--strict-nullable`](model-customization.md#strict-nullable) - Treat default field as a non-nullable field.
- [`--strict-refs`](general-options.md#strict-refs) - Treat unresolved local `$ref` JSON pointers as errors.
- [`--strict-types`](typing-customization.md#strict-types) - Enable strict type validation for specified Python types.
- [`--strip-default-none`](model-customization.md#strip-default-none) - Remove fields with None as default value from generated mode...
- [`--target-pydantic-version`](model-customization.md#target-pydantic-version) - Target Pydantic version for generated code compatibility.
- [`--target-python-version`](model-customization.md#target-python-version) - Target Python version for generated code syntax and imports.
- [`--treat-dot-as-module`](template-customization.md#treat-dot-as-module) - Treat dots in schema names as module separators.
- [`--type-mappings`](typing-customization.md#type-mappings) - Override default type mappings for schema formats.
- [`--type-overrides`](typing-customization.md#type-overrides) - Replace schema model types with custom Python types via JSON...
- [`--union-mode`](model-customization.md#union-mode) - Union mode for combining anyOf/oneOf schemas (smart or left_...
- [`--update-lock`](general-options.md#update-lock) - Create or atomically update the selected remote lock after g...
- [`--url`](base-options.md#url) - Fetch a schema from a URL with custom HTTP headers.
- [`--use-annotated`](typing-customization.md#use-annotated) - Use typing.Annotated for Field() with constraints.
- [`--use-attribute-docstrings`](field-customization.md#use-attribute-docstrings) - Generate field descriptions as attribute docstrings instead ...
- [`--use-closed-typed-dict`](typing-customization.md#use-closed-typed-dict) - Generate TypedDict with PEP 728 closed/extra_items (default:...
- [`--use-decimal-for-multiple-of`](typing-customization.md#use-decimal-for-multiple-of) - Generate Decimal types for fields with multipleOf constraint...
- [`--use-default`](model-customization.md#use-default) - Use default values from schema in generated models.
- [`--use-default-factory-for-optional-nested-models`](model-customization.md#use-default-factory-for-optional-nested-models) - Generate default_factory for optional nested model fields.
- [`--use-default-kwarg`](model-customization.md#use-default-kwarg) - Use default= keyword argument instead of positional argument...
- [`--use-double-quotes`](template-customization.md#use-double-quotes) - Use double quotes for string literals in generated code.
- [`--use-enum-values-in-discriminator`](field-customization.md#use-enum-values-in-discriminator) - Use enum values in discriminator mappings for union types.
- [`--use-exact-imports`](template-customization.md#use-exact-imports) - Import exact types instead of modules.
- [`--use-field-description`](field-customization.md#use-field-description) - Include schema descriptions as Field docstrings.
- [`--use-field-description-example`](field-customization.md#use-field-description-example) - Add field examples to docstrings.
- [`--use-frozen-field`](model-customization.md#use-frozen-field) - Generate frozen (immutable) field definitions for readOnly p...
- [`--use-generic-base-class`](model-customization.md#use-generic-base-class) - Generate a shared base class with model configuration to avo...
- [`--use-generic-container-types`](typing-customization.md#use-generic-container-types) - Use generic container types (Sequence, Mapping) for type hin...
- [`--use-inline-field-description`](field-customization.md#use-inline-field-description) - Add field descriptions as inline comments.
- [`--use-missing-sentinel`](model-customization.md#use-missing-sentinel) - Use Pydantic's MISSING sentinel for unset optional BaseModel...
- [`--use-msgspec-nullable-enum-alias`](model-customization.md#use-msgspec-nullable-enum-alias) - Write a msgspec.Struct enum that lists null as an Enum and a...
- [`--use-msgspec-tagged-unions`](model-customization.md#use-msgspec-tagged-unions) - Write a msgspec.Struct discriminated union as tagged structs...
- [`--use-non-positive-negative-number-constrained-types`](typing-customization.md#use-non-positive-negative-number-constrained-types) - Use NonPositive/NonNegative types for number constraints.
- [`--use-object-type`](typing-customization.md#use-object-type) - Use object instead of Any for unspecified object and array v...
- [`--use-one-literal-as-default`](model-customization.md#use-one-literal-as-default) - Use single literal value as default when enum has only one o...
- [`--use-operation-id-as-name`](openapi-only-options.md#use-operation-id-as-name) - Use OpenAPI operationId as the generated function/class name...
- [`--use-pendulum`](typing-customization.md#use-pendulum) - Use pendulum types for date, time, and duration fields.
- [`--use-root-model-sequence-interface`](model-customization.md#use-root-model-sequence-interface) - Make non-null sequence-like Pydantic v2 RootModel classes im...
- [`--use-root-model-type-alias`](typing-customization.md#use-root-model-type-alias) - Generate RootModel as type alias format for better mypy supp...
- [`--use-schema-description`](field-customization.md#use-schema-description) - Use schema description as class docstring.
- [`--use-serialization-alias`](field-customization.md#use-serialization-alias) - Use serialization_alias instead of alias for field aliasing ...
- [`--use-serialize-as-any`](model-customization.md#use-serialize-as-any) - Wrap fields with subtypes in Pydantic's SerializeAsAny.
- [`--use-single-line-docstring`](field-customization.md#use-single-line-docstring) - Emit short docstrings on a single line.
- [`--use-specialized-enum`](typing-customization.md#use-specialized-enum) - Generate StrEnum/IntEnum for string/integer enums (Python 3....
- [`--use-standard-collections`](typing-customization.md#use-standard-collections) - Use built-in dict/list instead of typing.Dict/List.
- [`--use-standard-primitive-types`](typing-customization.md#use-standard-primitive-types) - Use Python standard library types for string formats instead...
- [`--use-status-code-in-response-name`](openapi-only-options.md#use-status-code-in-response-name) - Include HTTP status code in response model names.
- [`--use-subclass-enum`](model-customization.md#use-subclass-enum) - Generate typed Enum subclasses for enums with specific field...
- [`--use-title-as-name`](field-customization.md#use-title-as-name) - Use schema title as the generated class name.
- [`--use-total-false-for-typed-dict`](typing-customization.md#use-total-false-for-typed-dict) - Generate TypedDict declarations with `total=False`.
- [`--use-tuple-for-fixed-items`](typing-customization.md#use-tuple-for-fixed-items) - Generate tuple types for arrays with items array syntax.
- [`--use-tuple-for-fixed-length-arrays`](typing-customization.md#use-tuple-for-fixed-length-arrays) - Generate tuple types for homogeneous fixed-length arrays.
- [`--use-type-alias`](typing-customization.md#use-type-alias) - Use TypeAlias instead of root models for type definitions (e...
- [`--use-type-alias-type`](typing-customization.md#use-type-alias-type) - Use runtime TypeAliasType objects for aliases before Python ...
- [`--use-type-checking-imports`](template-customization.md#use-type-checking-imports) - Allow Ruff to move typing-only imports into TYPE_CHECKING bl...
- [`--use-typed-nullable-map-values`](typing-customization.md#use-typed-nullable-map-values) - Type the values of nullable maps as their schemas say instea...
- [`--use-union-operator`](typing-customization.md#use-union-operator) - Use | operator for Union types (PEP 604).
- [`--use-unique-items-as-set`](typing-customization.md#use-unique-items-as-set) - Generate set types for arrays with uniqueItems constraint.
- [`--validation`](openapi-only-options.md#validation) - Enable validation constraints (deprecated, use --field-const...
- [`--validators`](template-customization.md#validators) - Add custom field validators to generated Pydantic v2 models.
- [`--version`](utility-options.md#version) - Show program version and exit
- [`--watch`](general-options.md#watch) - Watch input file(s) for changes and regenerate output automa...
- [`--watch-delay`](general-options.md#watch-delay) - Set debounce delay in seconds for watch mode.
- [`--wrap-string-literal`](template-customization.md#wrap-string-literal) - Wrap long string literals across multiple lines.

---

# Help

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/help/

## `--help` {#help}

Show help message and exit.

Displays all available command-line options with their descriptions and default values.

**Aliases:** `-h`

!!! tip "Usage"

    ```bash
    datamodel-codegen --help # (1)!
    ```

    1. :material-arrow-left: `--help` - the option documented here

??? example "Output"

    ```text
    usage: datamodel-codegen [-h] [--input INPUT] [--url URL] ...

    Generate Python data models from schema files.

    options:
      -h, --help            show this help message and exit
      --input INPUT         Input file path (default: stdin)
      ...
    ```

---

# Version

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/version/

## `--version` {#version}

Show program version and exit.

Displays the installed version of datamodel-code-generator.

!!! tip "Usage"

    ```bash
    datamodel-codegen --version # (1)!
    ```

    1. :material-arrow-left: `--version` - the option documented here

??? example "Output"

    ```text
    datamodel-codegen version: 0.x.x
    ```

---

# Debug

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/debug/

## `--debug` {#debug}

Show debug messages during code generation.

Enables verbose debug output to help troubleshoot issues with schema parsing
or code generation. Requires the `debug` extra to be installed.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --debug # (1)!
    ```

    1. :material-arrow-left: `--debug` - the option documented here

!!! warning "Requires extra dependency"

    The debug feature requires the `debug` extra:

    ```bash
    pip install 'datamodel-code-generator[debug]'
    ```

---

# Profile

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/profile/

## `--profile` {#profile}

Use a named profile from pyproject.toml configuration.

Profiles allow you to define multiple named configurations in your pyproject.toml
file. Each profile can override the default settings with its own set of options.

**Related:** [pyproject.toml Configuration](../../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --profile strict # (1)!
    ```

    1. :material-arrow-left: `--profile` - the option documented here

??? example "Configuration (pyproject.toml)"

    ```toml
    [tool.datamodel-codegen]
    # Default configuration
    output-model-type = "pydantic_v2.BaseModel"

    [tool.datamodel-codegen.profiles.strict]
    # Strict profile with additional options
    strict-types = ["str", "int", "float", "bool"]
    strict-nullable = true

    [tool.datamodel-codegen.profiles.dataclass]
    # Dataclass profile
    output-model-type = "dataclasses.dataclass"
    ```

    Use profiles:

    ```bash
    # Use the strict profile
    datamodel-codegen --input schema.json --profile strict

    # Use the dataclass profile
    datamodel-codegen --input schema.json --profile dataclass
    ```

---

# Job

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/job/

## `--job` {#job}

Run one or more named generation jobs declared in `pyproject.toml` (experimental). Jobs are
executed sequentially in TOML declaration order, even when `--job` is supplied
in a different order.

!!! warning "Experimental"

    Named batch jobs are experimental; their configuration schema, batch output,
    and transactional/watch execution contracts may change.

**Related:** [pyproject.toml Configuration](../../pyproject_toml.md),
[`--all-jobs`](all-jobs.md#all-jobs), [`--diff-against`](../general-options.md#diff-against)

!!! tip "Usage"

    ```bash
    datamodel-codegen --job api
    datamodel-codegen --job api --job events --check
    ```

??? example "Configuration (pyproject.toml)"

    ```toml
    [tool.datamodel-codegen.profiles.strict]
    use-annotated = true

    [tool.datamodel-codegen.jobs.api]
    profile = "strict"
    input = "schemas/openapi.yaml"
    output = "src/models/api.py"

    [tool.datamodel-codegen.jobs.events]
    input = "schemas/events.json"
    output = "src/models/events.py"
    ```

Jobs require their own `input` and `output`. A job can select one reusable
profile using `profile = "name"`. Settings are resolved as base configuration,
job profile, job settings, then safe batch-wide CLI overrides. `--input`,
`--url`, `--input-model`, `--output`, and `--profile` cannot be combined with
job selection. `--diff-against` also cannot be combined with named jobs: compare
one profile or input at a time. With `--watch`, one outer scheduler watches the
selected jobs' combined dependency graph and `pyproject.toml`. Every event replans and
transactionally reruns the complete selection; failures retain the published
outputs and continue watching for recovery.

A job whose settings select `generate-server` also generates the FastAPI server
package, and such jobs can share one models `output`; see [Batch jobs](../../fastapi-server.md#batch-jobs).

---

# All Jobs

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/all-jobs/

## `--all-jobs` {#all-jobs}

Run every named generation job from `[tool.datamodel-codegen.jobs]` in declaration
order (experimental).

!!! warning "Experimental"

    Named batch jobs are experimental; their configuration schema, batch output,
    and transactional/watch execution contracts may change.

**Related:** [`--job`](job.md#job), [`--diff-against`](../general-options.md#diff-against),
[pyproject.toml Configuration](../../pyproject_toml.md)

!!! tip "Usage"

    ```bash
    datamodel-codegen --all-jobs
    datamodel-codegen --all-jobs --check
    datamodel-codegen --all-jobs --output-format json
    datamodel-codegen --all-jobs --watch
    ```

All selected jobs are validated before generation starts. Jobs that write to
stdout, or whose output or model-metadata paths overlap, are rejected before
any generated file is written. With `--output-format json`, one `batch`
payload contains the result of every job.

`--diff-against` is intentionally unavailable for every named-job execution,
including a single selected job. Keeping one contract across `--job` and
`--all-jobs` avoids ambiguous partial support when the selection grows. Run the
comparison for one profile or input instead.

With `--watch`, changes to `pyproject.toml` replan the complete job membership.
All selected local dependencies are watched as one graph, and every event reruns
and publishes the whole batch transactionally rather than rebuilding only one
job.

---

# Install Skill

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/install-skill/

## `--install-skill` {#install-skill}

Install the bundled experimental `datamodel-code-generator` Agent Skill for Codex or Claude Code, then exit.

The default `project` scope installs the skill in the current project's
`.agents/skills/` directory for Codex or `.claude/skills/` directory for Claude
Code. Use `--skill-scope user` to install the same skill below your home
directory instead.

!!! tip "Usage"

    ```bash
    datamodel-codegen --install-skill codex # (1)!
    datamodel-codegen --install-skill claude-code --skill-scope user # (2)!
    datamodel-codegen --install-skill codex --overwrite-skill # (3)!
    ```

    1. :material-arrow-left: Install for Codex in `.agents/skills/` for the current project
    2. :material-arrow-left: Install for Claude Code in `~/.claude/skills/`
    3. :material-arrow-left: Replace an existing regular skill directory

For safety, an existing skill directory is left untouched unless
`--overwrite-skill` is supplied. Symlinks and non-directory targets are never
replaced.

---

# Overwrite Skill

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/overwrite-skill/

## `--overwrite-skill` {#overwrite-skill}

Replace an existing regular Agent Skill directory when installing with
`--install-skill`.

Without this option, an existing skill is preserved and the command exits with
an error. Symlinks and non-directory targets are never overwritten.

    datamodel-codegen --install-skill codex --overwrite-skill

---

# Skill Scope

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/skill-scope/

## `--skill-scope` {#skill-scope}

Choose whether `--install-skill` installs the bundled Agent Skill for the
current project or for the current user. The default is `project`.

`project` uses `.agents/skills/` for Codex and `.claude/skills/` for Claude
Code below the current working directory. `user` uses the matching directory
below your home directory.

    datamodel-codegen --install-skill codex --skill-scope project
    datamodel-codegen --install-skill claude-code --skill-scope user

---

# No Color

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/no-color/

## `--no-color` {#no-color}

Disable colorized output.

By default, datamodel-codegen uses colored output for better readability.
Use this option to disable colors, which is useful for CI/CD pipelines
or when redirecting output to files.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --no-color # (1)!
    ```

    1. :material-arrow-left: `--no-color` - the option documented here

!!! note "Environment variable"

    You can also disable colors by setting the `NO_COLOR` environment variable:

    ```bash
    NO_COLOR=1 datamodel-codegen --input schema.json
    ```

---

# Generate Prompt

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/generate-prompt/

## `--generate-prompt` {#generate-prompt}

Generate a prompt for consulting LLMs about CLI options.

Outputs a formatted prompt containing your current options, all available
options by category, and full help text. Pipe to CLI LLM tools or copy
to clipboard for web-based LLM chats.

Use `--output-format json` when an LLM agent or tool should consume structured
option metadata instead of Markdown.
Use `--output-format-json-schema generate-prompt` when the agent needs the JSON
Schema for that structured payload, such as when defining a tool contract.

**See also:** [LLM Integration](../../llm-integration.md) for detailed usage examples

!!! note "For LLM agents"

    See [LLM Integration: If You Are an LLM Agent](../../llm-integration.md#if-you-are-an-llm-agent)
    for workflow guidance.

!!! tip "Usage"

    ```bash
    datamodel-codegen --generate-prompt # (1)!
    datamodel-codegen --generate-prompt "How do I generate strict types?" # (2)!
    datamodel-codegen --generate-prompt --output-format json # (3)!
    datamodel-codegen --output-format-json-schema generate-prompt # (4)!
    ```

    1. :material-arrow-left: `--generate-prompt` - generate prompt without a question
    2. :material-arrow-left: Include a specific question in the prompt
    3. :material-arrow-left: Emit structured JSON for LLM/tool ingestion
    4. :material-arrow-left: Emit JSON Schema for structured prompt JSON

??? example "Quick Examples"

    **Pipe to CLI tools:**
    ```bash
    datamodel-codegen --generate-prompt | claude -p    # Claude Code
    datamodel-codegen --generate-prompt | codex exec   # OpenAI Codex
    datamodel-codegen --generate-prompt --output-format json | codex exec
    ```

    **Copy to clipboard:**
    ```bash
    datamodel-codegen --generate-prompt | pbcopy      # macOS
    datamodel-codegen --generate-prompt | xclip -selection clipboard  # Linux
    datamodel-codegen --generate-prompt | clip.exe    # WSL2
    ```

    **Ask about an existing OpenAPI command:**
    ```bash
    datamodel-codegen \
        --input openapi.yaml \
        --input-file-type openapi \
        --output models.py \
        --output-model-type pydantic_v2.BaseModel \
        --target-python-version 3.12 \
        --generate-prompt "Find the minimal options for strict API response models." \
        | claude -p
    ```

    **Review a command with current options:**
    ```bash
    datamodel-codegen \
        --input schema.json \
        --output models.py \
        --output-model-type pydantic_v2.BaseModel \
        --generate-prompt "Review this command for stable generated output in CI." \
        | claude -p
    ```

---

# List Deprecations

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/list-deprecations/

## `--list-deprecations` {#list-deprecations}

List registered deprecations and scheduled breaking changes, then exit.

The option reads from the central deprecation registry used by runtime warnings,
generated documentation, and release-note snippets.

    datamodel-codegen --list-deprecations
    datamodel-codegen --list-deprecations json
    datamodel-codegen --list-deprecations markdown

---

# List Experimental

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/list-experimental/

## `--list-experimental` {#list-experimental}

List registered experimental features, then exit.

The optional format argument can be `table`, `json`, or `markdown`. The default is `table`.

The option reads from the central experimental feature registry used by
generated documentation and release-note snippets.

    datamodel-codegen --list-experimental
    datamodel-codegen --list-experimental json
    datamodel-codegen --list-experimental markdown

---

# Output Format

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/output-format/

## `--output-format` {#output-format}

Choose the command output format.

The default output format is `text`. Use `json` when another program or LLM
agent should inspect structured output.

For backward compatibility, text stdout concatenates generated modules and does
not preserve their paths. Use `--fail-on-multi-module-stdout` to reject that
case, `--output <directory>` to preserve files, or `--output-format json` for
structured stdout. The fail option takes precedence over automatic repair of an
unusable modular stdout result, so an explicitly requested guard always rejects
the modular result instead of coalescing it.

In normal generation mode, `--output-format json` wraps generated modules in a
structured payload on stdout. If `--output` is also supplied, files are still
written to disk and the JSON payload mirrors the generated files. `--check`
also supports JSON output for difference reports. `--watch` keeps its existing
text output contract and does not support `--output-format json`.

Structured JSON is emitted on stdout for successful commands and for `--check`
difference reports. CLI usage errors, validation errors, and runtime generation
errors continue to use text on stderr with a non-zero exit code.

Generation JSON includes the normalized requested output path in top-level
`output` when `--output` is supplied, or `null` for stdout generation.
`files[].path` is the output file name for single-file disk output, and the
path relative to the output directory for directory output. For stdout-only
single-file generation it is `null`, and for multi-module stdout generation it
is the generated module path.

With `--generate-server` or `--generate-client`, the generation, check, and
input-diff payloads also have a `target` object: `package` is the import path
of the generated package, and `dependencies` lists its runtime requirements as
PEP 508 strings, the ones the `uv add` command on stderr names. A check or input
diff lists those of the current input, and `implied` the model settings the run
left unset and the target set, when there are any: an object with the keys
`openapi-scopes`, `target-python-version`, `use-missing-sentinel`,
`target-pydantic-version`, `use-msgspec-tagged-unions`, and
`use-msgspec-nullable-enum-alias`, each present only when the target set it. Payloads of model-only generation leave `target` out. The generation payload's `target` also carries the next steps that
stderr prints: `readme`, the path of the package README; for a server,
`entrypoint` (`app`, the import string of the application in `main.py`, and
`path`) and `implementation`, one entry for each module of yours that `main.py`
imports (`module`, `name`, `path`, and `created`, true when the run wrote it with
stubs, and whose `path` names the `__init__.py` of a module you made a package);
and for a client, `usage`, code that calls its first operation. Its paths are
relative like those of `files`.

Use `--output-format json` with `--generate-prompt` to emit structured option
metadata instead of Markdown. Use `--output-format-json-schema` when an LLM
agent or tool needs the schema for a JSON payload.

Schema targets are intentionally scoped. `generate-prompt` emits the
`PromptPayload` schema for `--generate-prompt --output-format json`.
`generation` emits only the `GenerationPayload` schema for generated-file JSON.
`model-metadata` emits the schema for files written by `--emit-model-metadata`.
`structured-output` emits the broader `StructuredOutputPayload` schema, a union
covering `GenerationPayload`, `PromptPayload`, `CommandOutputPayload`, and
`CheckOutputPayload`. Structured payloads use `kind` as the discriminator.

!!! tip "Usage"

    ```bash
    datamodel-codegen --input schema.json --output-format text # (1)!
    datamodel-codegen --input schema.json --output-format json # (2)!
    datamodel-codegen --generate-prompt --output-format json # (3)!
    datamodel-codegen --output-format-json-schema generation # (4)!
    datamodel-codegen --output-format-json-schema generate-prompt # (5)!
    datamodel-codegen --output-format-json-schema model-metadata # (6)!
    datamodel-codegen --output-format-json-schema structured-output # (7)!
    ```

    1. :material-arrow-left: Emit the default generated Python text
    2. :material-arrow-left: Emit structured JSON containing generated files
    3. :material-arrow-left: Emit structured JSON with current options and argparse metadata
    4. :material-arrow-left: Emit JSON Schema for generated-file JSON output
    5. :material-arrow-left: Emit JSON Schema for structured prompt JSON
    6. :material-arrow-left: Emit JSON Schema for generated model metadata JSON
    7. :material-arrow-left: Emit JSON Schema for any structured command JSON output

??? example "Generation JSON output"

    ```json
    {
      "version": 1,
      "format": "json",
      "kind": "generation",
      "output": null,
      "files": [
        {
          "path": null,
          "content": "# generated by datamodel-codegen:\n..."
        }
      ]
    }
    ```

??? example "Prompt JSON output"

    ```bash
    datamodel-codegen \
        --input schema.json \
        --output-model-type pydantic_v2.BaseModel \
        --generate-prompt "Choose strict model options." \
        --output-format json
    ```

---

# Output Format Json Schema

Source: https://datamodel-code-generator.koxudaxi.dev/cli-reference/manual/output-format-json-schema/

## `--output-format-json-schema` {#output-format-json-schema}

Output JSON Schema for a JSON output format and exit.

Use this when an LLM agent, tool call definition, or validation layer needs the
contract before consuming JSON output. The schema is emitted separately from the
JSON payload so tools can fetch the contract once and validate later command
output independently.

Currently supported schema targets:

- `generate-prompt`: schema for `--generate-prompt --output-format json`
- `generation`: schema for normal generation with `--output-format json`
- `model-metadata`: schema for files emitted by `--emit-model-metadata`
- `structured-output`: tagged union schema for all structured command outputs,
  discriminated by `kind`
- `config`: schema for JSON-valued configuration options

!!! tip "Usage"

    ```bash
    datamodel-codegen --output-format-json-schema generate-prompt # (1)!
    datamodel-codegen --output-format-json-schema generation # (2)!
    datamodel-codegen --output-format-json-schema model-metadata # (3)!
    datamodel-codegen --output-format-json-schema structured-output # (4)!
    datamodel-codegen --output-format-json-schema config # (5)!
    datamodel-codegen --generate-prompt --output-format json # (6)!
    datamodel-codegen --input schema.json --emit-model-metadata model-map.json # (7)!
    ```

    1. :material-arrow-left: Emit the JSON Schema for structured prompt output
    2. :material-arrow-left: Emit the JSON Schema for generated-file output
    3. :material-arrow-left: Emit the JSON Schema for generated model metadata
    4. :material-arrow-left: Emit the JSON Schema for all structured command outputs
    5. :material-arrow-left: Emit the JSON Schema for JSON-valued configuration options
    6. :material-arrow-left: Emit prompt payloads that match the prompt schema
    7. :material-arrow-left: Emit metadata payloads that match the model metadata schema

---

# Conformance Dashboard

Source: https://datamodel-code-generator.koxudaxi.dev/conformance/

<!-- Generated by scripts/build_conformance_docs.py. Do not edit manually. -->

This page summarizes the external conformance and end-to-end corpus checks that CI runs for datamodel-code-generator. The table is generated from `tox.ini`, `.github/workflows/test.yaml`, local runner scripts, and JSON-Schema-Test-Suite pytest metadata.

These suites are compatibility and coverage signals. They show that CI exercises datamodel-code-generator against pinned upstream corpora; they do not claim complete specification compliance.

| Suite name | Input format / scope | Source corpus or upstream project | Local runner script | tox environment | CI job name | Expected corpus size/count | External checkout/network in CI | What the suite proves |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| W3C XML Schema Test Suite | XML Schema (`.xsd`) generation from valid schema documents | [w3c/xsdtests](https://github.com/w3c/xsdtests) @ `7bc3365c652a322f3d762021b3879eb92dae7e30` | `scripts/run_w3c_xmlschema_e2e.py` | `w3c-xmlschema-e2e` | `e2e` (`e2e`) | 5,284 valid schemaDocument entries; 5,283 unique valid schemaDocument paths | Yes; cached external checkout, network on cache miss | CI exercises XML Schema generation against valid schema documents in the pinned W3C test suite and imports the generated Python modules. |
| JSON-Schema-Test-Suite | JSON Schema generated Pydantic v2 model validation for configured drafts | [json-schema-org/JSON-Schema-Test-Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite) @ `fe8c2f0de2041943975932b6bf4bd882625b6cfb` | `scripts/run_jsonschema_suite_conformance.py` | `jsonschema-suite-conformance` | `e2e` (`e2e`) | 640 groups / 2,226 tests for default drafts `draft7`, `draft2020-12` (asserted by pytest) | Yes; cached external checkout, network on cache miss | CI exercises generated Pydantic v2 models against JSON-Schema-Test-Suite expectations for the configured drafts, with unsupported cases classified in tests. |
| AsyncAPI spec JSON Schemas | Stable AsyncAPI specification JSON Schema files used as JSON Schema input | [asyncapi/spec-json-schemas](https://github.com/asyncapi/spec-json-schemas) @ `469c2b2bf5ed88e0cdf1e48975b93a87c710d229` | `scripts/run_asyncapi_spec_json_schemas_e2e.py` | `asyncapi-spec-json-schemas-e2e` | `e2e` (`e2e`) | 12 schemas | Yes; cached external checkout, network on cache miss | CI exercises generation and import of Python models from stable AsyncAPI specification JSON Schema files, including local handling of HTTP references. |
| Apache Avro schema pass corpus | Apache Avro schema pass files from the upstream C test corpus | [apache/avro](https://github.com/apache/avro) @ `9110c693767c1dde2665b2b57939333478b12036` | `scripts/run_apache_avro_schema_pass_e2e.py` | `apache-avro-schema-pass-e2e` | `e2e` (`e2e`) | 28 schemas | Yes; cached external checkout, network on cache miss | CI exercises Avro generation against upstream pass-corpus schemas and imports the generated Python module. |
| Protocol Buffers official corpus | Official Protocol Buffers `.proto` files selected by the local runner | [protocolbuffers/protobuf](https://github.com/protocolbuffers/protobuf) @ `4376cba55d9e2f44f7e317d9c10e0259d145f8cf`; sparse checkout: `src`, `conformance`, `benchmarks` | `scripts/run_protobuf_official_e2e.py` | `protobuf-official-e2e` | `e2e` (`e2e`) | 65 schemas | Yes; cached external checkout, network on cache miss | CI exercises Protocol Buffers generation against supported files in the pinned official corpus subset and imports the generated Python module. |

## Generated Sources

- tox environments and runner script paths are derived from `tox.ini`.
- CI job names, upstream checkout pins, cache usage, and workflow `--expected-*` arguments are derived from `.github/workflows/test.yaml`.
- JSON-Schema-Test-Suite default draft counts are derived from `tests/main/payload_validation/json_schema_suite.py` because the workflow delegates count assertions to pytest.

---

# Performance Benchmarks

Source: https://datamodel-code-generator.koxudaxi.dev/performance-benchmarks/

<!-- Generated by scripts/build_release_benchmark_docs.py. Do not edit manually. -->

This page tracks datamodel-code-generator release and main-branch benchmark results collected on GitHub Actions. The data covers only datamodel-code-generator and uses Ubuntu runners so release-to-release changes can be compared without mixing in third-party generator results. Automatic backfills select versions from PyPI download-by-version data when that public dataset is available.

datamodel-code-generator supports many schema styles and production use cases, so it includes a broad set of useful options. As releases add more capabilities, these benchmarks help keep the implementation measured, managed, and tuned so code generation stays fast in everyday use.

## Scenario Guide

Each scenario combines an input type with a case size. This guide is generated from the scenario keys in the benchmark JSON and the collector case definitions, so it changes when the benchmark matrix changes.

| Scenario | Input fixture | Formatters | Represents |
| --- | --- | --- | --- |
| Small / JSON Schema | `tests/data/jsonschema/person.json` | `default` (black/isort default), `builtin` (Built-in), `ruff` (Ruff) | Compact fixture that emphasizes CLI startup, parsing, and formatter overhead for JSON Schema to Pydantic v2 model generation. |
| Small / OpenAPI | `tests/data/openapi/api.yaml` | `default` (black/isort default), `builtin` (Built-in), `ruff` (Ruff) | Compact fixture that emphasizes CLI startup, parsing, and formatter overhead for OpenAPI component resolution and Pydantic v2 model generation. |
| Large / JSON Schema | `tests/data/performance/large_models.json` | `default` (black/isort default), `builtin` (Built-in), `ruff` (Ruff) | Larger fixture that emphasizes parser and model graph throughput for JSON Schema to Pydantic v2 model generation. |
| Large / OpenAPI | `tests/data/performance/openapi_large.yaml` | `default` (black/isort default), `builtin` (Built-in), `ruff` (Ruff) | Larger fixture that emphasizes parser and model graph throughput for OpenAPI component resolution and Pydantic v2 model generation. |

## Interpreting Metrics

- `median_ms` is the primary comparison value: it is the median generation duration after warmup runs, and lower is faster.
- `min_ms`, `max_ms`, and `stdev_ms` describe the measured spread for the same row; wide ranges usually mean CI runner noise rather than a deliberate code change.
- Formatter comparisons are scoped to the same scenario and version. `default` is the black/isort default baseline, while `builtin` and `ruff` ratios compare their medians to that baseline.
- `ok` rows have timing data. `unsupported` means the formatter or option was unavailable in that release. `failed` means installation or command execution failed, so timing cells are intentionally empty.

## Historical Trends

The benchmark data on this page is loaded from `docs/data/release-benchmarks.json` and rendered in the browser. Release runs update that JSON file directly, so the published page reflects new release measurements after the docs deployment without rewriting this Markdown file.

<div class="release-benchmark-app" data-release-benchmark-app data-release-benchmark-state="available">
  <p class="release-benchmark-app__status" data-release-benchmark-status>Loading benchmark data...</p>
  <noscript>JavaScript is required to load the release benchmark data.</noscript>
</div>

## Collection Policy

- The benchmark workflow runs on `ubuntu-24.04`.
- Benchmark results are collected on GitHub Actions CI runners, so median timings can vary slightly with runner load and workflow timing; rerun benchmarks before treating small differences as regressions.
- The Python version is the workflow input, defaulting to the latest configured CI Python.
- Release packages are installed from PyPI in isolated virtual environments.
- Every benchmark update measures `main` from an exact commit resolved at workflow start and replaces the previous `main` snapshot.
- Input coverage currently focuses on OpenAPI and JSON Schema.
- Historical updates commit `docs/data/release-benchmarks.json`; the page renders that JSON client-side.

---

# Deprecations

Source: https://datamodel-code-generator.koxudaxi.dev/deprecations/

<!-- Generated by scripts/build_deprecation_docs.py. Do not edit manually. -->

This page lists deprecations and scheduled breaking changes.

| ID | Status | Kind | Target | Since | Removal | Replacement |
|----|--------|------|--------|-------|---------|-------------|
| `format.default-formatters` | active | behavior | `Default formatters` | 0.52.0 | TBD | Set formatters explicitly, for example black and isort or builtin. |
| `behavior.pydantic-v2-use-annotated-default` | active | behavior | `Pydantic v2 default for --use-annotated` | 0.52.1 | TBD | Explicitly pass --use-annotated or --no-use-annotated. |
| `behavior.remote-ref-default` | active | behavior | `Remote $ref fetching without --allow-remote-refs` | 0.56.0 | TBD | Pass --allow-remote-refs for trusted remote schemas, or --no-allow-remote-refs to block HTTP(S) $ref fetching. |
| `cli.allow-extra-fields` | active | cli-option | `--allow-extra-fields` | 0.31.0 | TBD | --extra-fields=allow |
| `cli.parent-scoped-naming` | active | cli-option | `--parent-scoped-naming` | 0.48.0 | TBD | --naming-strategy parent-prefixed |
| `cli.set-default-enum-member` | scheduled | cli-option | `--set-default-enum-member` | 0.76.0 | TBD | --deserialize-default-values enum |
| `cli.validation` | active | cli-option | `--validation` | 0.24.0 | TBD | --field-constraints |
| `config.json-config-strict-validation` | active | config | `JSON configuration values accepted by legacy validation` | 0.64.2 | TBD | Update the JSON configuration to match --output-format-json-schema config. |
| `config.yaml-non-lowercase-bool` | active | config | `YAML bool values True, False, TRUE, FALSE` | 0.48.0 | TBD | Use lowercase true or false. |
| `dependency.black-minimum` | active | dependency | `Black <24.3.0` | 0.78.0 | TBD | Upgrade Black to >=24.3.0 before the later support change. |
| `dependency.external-formatters-optional` | active | dependency | `Black/isort installation` | 0.78.0 | TBD | Declare the black/isort extras for the external formatters you select. |
| `dependency.pydantic-runtime-minimum` | active | dependency | `DCG runtime Pydantic <2.8.2` | 0.78.0 | TBD | Upgrade DCG runtime Pydantic to >=2.8.2; generated-code targets are unchanged. |
| `dependency.isort-minimum` | active | dependency | `isort <6` | 0.78.0 | TBD | Upgrade isort to >=6,<9 before the later support change. |
| `python-api.python-version-has-type-alias` | active | python-api | `PythonVersion.has_type_alias` | 0.52.1 | TBD | - |
| `schema.jsonschema-items-array` | active | schema | `JSON Schema Draft 2020-12 items array tuple validation` | 0.53.0 | TBD | Use prefixItems. |
| `schema.openapi-nullable` | active | schema | `OpenAPI 3.1 nullable keyword` | 0.53.0 | TBD | Use type arrays such as type: ["string", "null"]. |
| `dependency.python-310-runtime` | active | dependency | `Running datamodel-code-generator on Python 3.10` | 0.84.0 | 0.85.0 | Run datamodel-code-generator on Python 3.11 or newer. |

## Details

### `format.default-formatters`

- **Status:** active
- **Kind:** behavior
- **Target:** `Default formatters`
- **Since:** 0.52.0
- **Planned removal:** TBD
- **Warning category:** `FutureWarning`
- **Replacement:** Set formatters explicitly, for example black and isort or builtin.

Default formatters will change to builtin. Set --formatters or --preset explicitly; see --help.

### `behavior.pydantic-v2-use-annotated-default`

- **Status:** active
- **Kind:** behavior
- **Target:** `Pydantic v2 default for --use-annotated`
- **Since:** 0.52.1
- **Planned removal:** TBD
- **Warning category:** `DeprecationWarning`
- **Replacement:** Explicitly pass --use-annotated or --no-use-annotated.

Pydantic v2 with --use-annotated is recommended for correct type annotations. In a future version, --use-annotated will be enabled by default for Pydantic v2.

### `behavior.remote-ref-default`

- **Status:** active
- **Kind:** behavior
- **Target:** `Remote $ref fetching without --allow-remote-refs`
- **Since:** 0.56.0
- **Planned removal:** TBD
- **Warning category:** `FutureWarning`
- **Replacement:** Pass --allow-remote-refs for trusted remote schemas, or --no-allow-remote-refs to block HTTP(S) $ref fetching.

Remote $ref fetching without --allow-remote-refs is deprecated.

The current default allows remote fetching for compatibility; the scheduled default is disabled. Private, loopback, link-local, and otherwise non-public network targets require --allow-private-network.

### `cli.allow-extra-fields`

- **Status:** active
- **Kind:** cli-option
- **Target:** `--allow-extra-fields`
- **Since:** 0.31.0
- **Planned removal:** TBD
- **Warning category:** `DeprecationWarning`
- **Replacement:** --extra-fields=allow

--allow-extra-fields is deprecated. Use --extra-fields=allow instead.

The replacement supports allow, forbid, and ignore modes.

### `cli.parent-scoped-naming`

- **Status:** active
- **Kind:** cli-option
- **Target:** `--parent-scoped-naming`
- **Since:** 0.48.0
- **Planned removal:** TBD
- **Warning category:** `DeprecationWarning`
- **Replacement:** --naming-strategy parent-prefixed

--parent-scoped-naming is deprecated. Use --naming-strategy parent-prefixed instead.

### `cli.set-default-enum-member`

- **Status:** scheduled
- **Kind:** cli-option
- **Target:** `--set-default-enum-member`
- **Since:** 0.76.0
- **Planned removal:** TBD
- **Warning category:** `DeprecationWarning`
- **Replacement:** --deserialize-default-values enum

--set-default-enum-member is deprecated. Use --deserialize-default-values enum instead.

### `cli.validation`

- **Status:** active
- **Kind:** cli-option
- **Target:** `--validation`
- **Since:** 0.24.0
- **Planned removal:** TBD
- **Warning category:** `DeprecationWarning`
- **Replacement:** --field-constraints

The `--validation` option is deprecated and will be removed in a future release. Use --field-constraints instead.

### `config.json-config-strict-validation`

- **Status:** active
- **Kind:** config
- **Target:** `JSON configuration values accepted by legacy validation`
- **Since:** 0.64.2
- **Planned removal:** TBD
- **Warning category:** `FutureWarning`
- **Replacement:** Update the JSON configuration to match --output-format-json-schema config.

JSON configuration values that do not match the documented schema are deprecated and will become validation errors in a future release.

### `config.yaml-non-lowercase-bool`

- **Status:** active
- **Kind:** config
- **Target:** `YAML bool values True, False, TRUE, FALSE`
- **Since:** 0.48.0
- **Planned removal:** TBD
- **Warning category:** `DeprecationWarning`
- **Replacement:** Use lowercase true or false.

Non-lowercase YAML bool values are deprecated. Use lowercase true or false instead.

### `dependency.black-minimum`

- **Status:** active
- **Kind:** dependency
- **Target:** `Black <24.3.0`
- **Since:** 0.78.0
- **Planned removal:** TBD
- **Warning category:** `FutureWarning`
- **Replacement:** Upgrade Black to >=24.3.0 before the later support change.

Support for Black <24.3.0 will end in a future release.

This is advance notice only. Current dependency ranges and compatibility remain unchanged.

### `dependency.external-formatters-optional`

- **Status:** active
- **Kind:** dependency
- **Target:** `Black/isort installation`
- **Since:** 0.78.0
- **Planned removal:** TBD
- **Warning category:** `FutureWarning`
- **Replacement:** Declare the black/isort extras for the external formatters you select.

Black/isort will become optional. Declare the corresponding extras; see --help.

This is advance notice only. Current dependency ranges and compatibility remain unchanged.

### `dependency.pydantic-runtime-minimum`

- **Status:** active
- **Kind:** dependency
- **Target:** `DCG runtime Pydantic <2.8.2`
- **Since:** 0.78.0
- **Planned removal:** TBD
- **Warning category:** `FutureWarning`
- **Replacement:** Upgrade DCG runtime Pydantic to >=2.8.2; generated-code targets are unchanged.

Support for DCG runtime Pydantic <2.8.2 will end in a future release.

This is advance notice only. Current dependency ranges and compatibility remain unchanged.

### `dependency.isort-minimum`

- **Status:** active
- **Kind:** dependency
- **Target:** `isort <6`
- **Since:** 0.78.0
- **Planned removal:** TBD
- **Warning category:** `FutureWarning`
- **Replacement:** Upgrade isort to >=6,<9 before the later support change.

Support for isort <6 will end in a future release.

This is advance notice only. Current dependency ranges and compatibility remain unchanged.

### `python-api.python-version-has-type-alias`

- **Status:** active
- **Kind:** python-api
- **Target:** `PythonVersion.has_type_alias`
- **Since:** 0.52.1
- **Planned removal:** TBD
- **Warning category:** `DeprecationWarning`

has_type_alias is deprecated and will be removed in a future version.

The project minimum Python version already supports TypeAlias.

### `schema.jsonschema-items-array`

- **Status:** active
- **Kind:** schema
- **Target:** `JSON Schema Draft 2020-12 items array tuple validation`
- **Since:** 0.53.0
- **Planned removal:** TBD
- **Warning category:** `UserWarning`
- **Replacement:** Use prefixItems.

items as array tuple validation is deprecated in Draft 2020-12. Use prefixItems instead.

### `schema.openapi-nullable`

- **Status:** active
- **Kind:** schema
- **Target:** `OpenAPI 3.1 nullable keyword`
- **Since:** 0.53.0
- **Planned removal:** TBD
- **Warning category:** `DeprecationWarning`
- **Replacement:** Use type arrays such as type: ["string", "null"].

nullable keyword is deprecated in OpenAPI 3.1, use type: ["string", "null"] instead.

### `dependency.python-310-runtime`

- **Status:** active
- **Kind:** dependency
- **Target:** `Running datamodel-code-generator on Python 3.10`
- **Since:** 0.84.0
- **Planned removal:** 0.85.0
- **Warning category:** `FutureWarning`
- **Replacement:** Run datamodel-code-generator on Python 3.11 or newer.

Running datamodel-code-generator on Python 3.10 is deprecated and will be removed in 0.85.0; run it on Python 3.11 or newer. --target-python-version 3.10 is unaffected.

Generating code for Python 3.10 with --target-python-version 3.10 is unchanged.

---

# Dependency migration notices

Source: https://datamodel-code-generator.koxudaxi.dev/dependency-migration/

This release prepares later changes. Black and isort remain the default formatters and required dependencies;
all current dependency ranges, compatibility code and minimum-version tests remain in place. Generation still
continues when formatters are omitted. The built-in formatter remains experimental.

## Choose formatting independently of the default

- Use `--formatters ruff-check ruff-format` when your project uses Ruff and generated code should follow its lint
  and formatting settings. Install `datamodel-code-generator[ruff]` when needed.
- Use `--formatters builtin` when you use no external formatter or prioritize generation speed and avoiding
  external formatter execution.
- Keep `--formatters black isort` to preserve your existing Black/isort policy and generated formatting.

The future builtin default is intended to reduce mandatory installation dependencies and version constraints.
It does not change the recommendation to use Ruff in projects standardized on Ruff. Packages and Ruff configuration
never trigger automatic formatter selection.

Configure the formatter once in `pyproject.toml` to avoid repeating CLI options:

```toml
[tool.datamodel-codegen]
formatters = ["ruff-check", "ruff-format"]
```

The new `standard-py310-20260909` through `standard-py314-20260909` and corresponding `practical` presets include
builtin. Presets also change other generation settings, so explicitly selecting only a formatter is the smallest
migration when you want to preserve those settings. Override a new preset with
`--formatters ruff-check ruff-format` or `--formatters black isort` as appropriate. Earlier dated presets do not
supply a formatter and continue to use the implicit Black/isort default and its warning unless overridden.
An explicit empty formatter list in pyproject or the Python API disables standard formatting.

Explicit formatter selection does not pin formatter versions, configuration or every byte of generated output.
Custom templates can continue using Black/isort or Ruff; builtin does not exhaustively validate custom-template
output. See [Formatter behavior](formatter-behavior.md) for scope and configuration details.

## Separate notices

| Notice | When it is emitted |
| --- | --- |
| Default formatter change | Effective formatters are unspecified, including older presets and custom formatters added to the implicit pipeline. |
| Black/isort optional installation | Black or isort is explicitly selected, including through resolved configuration or a formatter-supplying preset. Not also emitted for an implicit pipeline. |
| Old Black/isort support | A selected formatter is below its proposed future minimum, whether the pipeline was implicit or explicit. Merely having it installed does not warn. |
| Old runtime Pydantic support | DCG generates code using Pydantic below 2.8.2 in its own runtime, even when generating dataclasses, TypedDict or msgspec models. |
| Python 3.10 runtime | DCG itself runs on Python 3.10 and generates code through the CLI or the Python API. `--target-python-version 3.10` alone does not warn. |

Each notice is registered separately as an active `FutureWarning`. The default formatter notice retains its
original 0.52.0 history; the formatter and dependency-floor notices are recorded for the planned 0.78.0 release,
and the Python 3.10 runtime notice is recorded since 0.84.0 with removal in 0.85.0. The registry contains the
[exact short messages](deprecations.md). Migration warnings are deduplicated within one CLI invocation, including
batch and watch regeneration. Non-generation operations such as help, version and listings do not emit them or
load dependency modules just to check versions. The Python API respects standard warning filters, including
`always`, `ignore` and `error`; the CLI continues to support `--disable-warnings`. Warnings do not enter stdout or
generated code.

## Prepare for optional Black/isort installation

The new `[black]` and `[isort]` extras currently repeat the mandatory dependency ranges and Emscripten markers;
`[all]` includes them. They prepare a stable installation spelling for the later optionalization. You do not need
to reinstall these currently mandatory dependencies merely because of this release.

For continued Black/isort use after the future default and installation changes, select both the dependencies and
formatter pipeline:

```bash
uvx --from 'datamodel-code-generator[black,isort]' \
  datamodel-codegen --input schema.json --output models.py \
  --formatters black isort
```

For a Python API or shared environment, declare `datamodel-code-generator[black,isort]` in your environment's
dependencies and pass `formatters=[Formatter.BLACK, Formatter.ISORT]`. Declare only the extras you actually use.
`uvx` can isolate the CLI's dependencies from application dependencies. Shared environments and API use remain
supported migration scenarios; application constraints alone do not imply a fixed long transition period.

## Proposed future dependency floors

These are follow-up targets, not changes to this release's requirements:

| Dependency | Current requirement | Proposed later requirement |
| --- | --- | --- |
| isort | `>=4.3.21,<9` | `>=6,<9` (keep 6, 7 and 8) |
| Black, Python <3.15 | `>=19.10b0` | `>=24.3.0` |
| Black, Python >=3.15 | `>=26.5` | Unchanged |
| Runtime Pydantic, Python <3.14 | `>=2,<3` | `>=2.8.2,<3` |
| Runtime Pydantic, Python >=3.14,<3.15 | `>=2.12,<3` | Unchanged |
| Runtime Pydantic, Python >=3.15 | `>=2.14,<3` | Unchanged |

No other dependency floor changes are proposed here. The generator continues using its existing numeric runtime
compatibility boundaries; no version selection is inferred from string ordering. The notice comparisons use
numeric release components and distinguish prereleases at the final-release boundary without relying on an
undeclared packaging dependency.

No removal version, date, or transition period has been specified. This release only announces the proposed
changes; there is no date-based removal or automatic requirement change.

Public lock searches included many old DCG versions and false-positive mentions in other packages' extras. Counts
from those searches are not user counts or impact estimates. Recent public usage includes explicit Black/isort,
builtin and Ruff. This is a migration policy informed by public examples and maintenance cost, not evidence that
almost nobody will be affected.

## Runtime Pydantic versus generated-code Pydantic

The proposed 2.8.2 floor applies to **DCG's runtime**, not the environment that consumes generated code.
`--target-pydantic-version` values such as 2, 2.11, 2.12 and 2.14 remain unchanged. Raising the runtime floor alone is not
a reason to delete every existing compatibility branch.

The following classification reflects the current source. Emitted code never depends on the installed Pydantic:
`model/pydantic_v2/version.py` keys every generated-code boundary on `--target-pydantic-version`. Leaving it unset
gives the newest supported feature forms, while config key naming keeps its existing rule (`populate_by_name` unless
the target is `2.11` or later); `2` means Pydantic 2.0+ compatible forms. Raising DCG's runtime floor therefore cannot
change generated output.

| Area | Classification and current effect | Follow-up test responsibility |
| --- | --- | --- |
| DCG configuration/internal Pydantic models | Internal runtime compatibility: validating generator configuration and constructing internal model/field objects relies on the installed Pydantic. | Keep the minimum DCG-runtime configuration and generation tests; reassess only when the actual floor changes. |
| Dataclass alias, 2.4 boundary | Generated-code compatibility: targets before 2.4 (`2`) use the `DataModelFieldBackport` alias fallback, which emits `Field` assignments with validation and serialization aliases for non-identifier aliases. | Generate alias cases on the new DCG runtime and execute them separately on supported consumer versions before removing fallback behavior. |
| `deprecated` / `json_schema_extra`, 2.7 boundary | Generated-code compatibility: targets before 2.7 (`2`) emit `deprecated` in `json_schema_extra`; unset, `2.11`, `2.12` and `2.14` emit `Field(deprecated=...)`. | Check emitted metadata and execute/schema-inspect generated models in consumer environments. |
| `regex_engine`, 2.5 boundary | Generated-code compatibility: the emitter adds `python-re` for pattern syntax no pydantic-core release supports, such as lookaround and backreferences, detected statically (see [Regular Expression Patterns](jsonschema.md#regular-expression-patterns)) for every target, and for `bytes` patterns only with an explicit `2.14` target, the first release that compiles them. Old generated models may still reject those expressions at runtime. | Retain regex pattern generation and consumer-runtime validation/known exclusions, independent of the DCG runtime floor. |
| Compiled alias patterns, 2.8 boundary | Generated-code compatibility: targets before 2.8 (`2`) keep string patterns that need Python's regex engine in type aliases and set `regex_engine="python-re"` on every generated model that reaches the alias, directly or through other models; a bare alias or a hand-written model then needs caller-side config. Unset, `2.11`, `2.12` and `2.14` emit compiled `re.compile(...)` patterns in the alias. XSD combined patterns stay compiled for every target. | Generate both forms on every DCG runtime and execute them on supported consumer versions. |
| RootModel, dictionary keys, forward references, 2.8 boundary | Generated-code compatibility: targets before 2.8 (`2`) sort models used as dictionary keys before their users; unset, `2.11`, `2.12` and `2.14` keep schema order. | Retain recursive RootModel and dictionary-key import/execution cases across generator and consumer environments. |
| `StringConstraints`, 2.1 boundary | Generated-code compatibility: targets before 2.1 (`2`) emit `Annotated[str, Field(...)]` for constrained strings with `--use-annotated`; unset, `2.11`, `2.12` and `2.14` emit `StringConstraints`. | Generate both forms on every DCG runtime and execute them on supported consumer versions. |
| Dataclass reference aliases, 2.10 boundary | Generated-code compatibility: targets before 2.10 (`2`) emit `Alias: TypeAlias = Model` for `pydantic_v2.dataclass` aliases of models; unset, `2.11`, `2.12` and `2.14` emit `TypeAliasType`. | Generate both forms on every DCG runtime and execute them on supported consumer versions. |
| Dataclass required `Field(...)` order, 2.13 boundary | Generated-code compatibility: `pydantic_v2.dataclass` keeps required fields written as `= Field(...)` in schema order for unset, `2`, `2.11` and `2.12`, where they can follow a field with a default; only an explicit `2.14` target writes them before the fields with defaults of the same class, the order `inspect.signature` needs on Pydantic 2.13 and later; Python 3.10 reads that signature while creating a subclass, which then fails at import. The order is not changed for an unset target because positional construction follows it, and the generator warns about each class that keeps such an order. | Generate both orders on every DCG runtime; construct the models positionally and read their signature on supported consumer versions. |
| Discriminator / Union | Both: internal schema/model construction and emitted union/discriminator annotations must agree; existing force-optional and payload cases exercise runtime-sensitive behavior. | Keep generation assertions and instantiate generated union cases on separately pinned consumer versions. |
| `additionalProperties` | Both: schema interpretation plus emitted typed extras, recursive references and runtime validators affect consumer behavior. | Preserve schema/alias/recursive extra-property tests and verify generated validation, rather than treating all failures as DCG-runtime-only. |
| Payload and generated-code execution | Both are currently exercised together in pinned environments: generated code is imported and validated using the same environment's Pydantic. | Split producer and consumer environments where necessary to retain old consumer coverage after raising DCG's own minimum. |

Current dedicated environments include `pydantic200` (2.0.0), `pydantic20` (2.0.3), `pydantic25` (2.5.3),
`pydantic212` (2.12.5), and `pydantic213` (2.13.4). Separate payload environments include
`py311-payload-runtime-min` (Pydantic 2.0.3 and msgspec 0.18), `py314-payload-runtime-min` (Pydantic 2.12 and
msgspec 0.20), and their latest counterparts. The payload and
execution suites contain runtime-specific exclusions and boundary expectations; they cannot be dropped just
because the generator's own floor increases. These environments and compatibility implementations are retained.

Future work should distinguish a minimum **producer** test running DCG from **consumer** tests that execute its
saved output in another Pydantic environment. First preserve alias, metadata, regex, recursive RootModel,
discriminator/Union, additional-properties and payload behavior; then identify which internal-only branches can
actually be removed. Changing target-version semantics would require a separate, explicit decision.

## Running on Python 3.10

Running datamodel-code-generator on Python 3.10 is deprecated in 0.84.0 and will be removed in 0.85.0, because
Python 3.10 reached end of life in October 2026. Generation on Python 3.10 emits a `FutureWarning`; run DCG on
Python 3.11 or newer to prepare. This concerns only the interpreter running DCG: generating code for Python 3.10
with `--target-python-version 3.10` is unchanged.

## Follow-up changes remain separate

1. Change the implicit default to builtin, retaining explicit Ruff and Black/isort choices.
2. Remove Black/isort from mandatory dependencies, retaining the extras and explicit dependency errors.
3. Raise the runtime dependency floors and reassess compatibility code and producer/consumer tests.

None of these three changes is performed by this preparation release.

---

# Experimental Features

Source: https://datamodel-code-generator.koxudaxi.dev/experimental/

<!-- Generated by scripts/build_experimental_docs.py. Do not edit manually. -->

This page lists features that are available but still experimental.

| ID | Kind | Target | Since | Tracking |
|----|------|--------|-------|----------|
| `behavior.batch-generation-jobs` | behavior | `[tool.datamodel-codegen.jobs], --job, --all-jobs` | 0.72.3 | - |
| `behavior.remote-reference-lock` | behavior | `datamodel-codegen.lock, --lockfile, --update-lock, and --locked` | 0.72.3 | - |
| `cli-option.generate-client` | cli-option | `--generate-client httpx2 and the --client-* options (and their [tool.datamodel-codegen] keys and generate() options)` | 0.84.0 | - |
| `cli-option.generate-schema-validators` | cli-option | `--generate-schema-validators` | 0.66.1 | - |
| `cli-option.generate-server` | cli-option | `--generate-server fastapi and the --server-* options (and their [tool.datamodel-codegen] keys and generate() options)` | 0.84.0 | - |
| `cli-option.install-skill` | cli-option | `--install-skill, --skill-scope, and --overwrite-skill` | 0.76.0 | - |
| `cli-option.schema-validator-type` | cli-option | `--schema-validator-type` | 0.66.1 | - |
| `cli-option.use-missing-sentinel` | cli-option | `--use-missing-sentinel` | 0.66.1 | - |
| `cli-option.use-type-alias` | cli-option | `--use-type-alias` | 0.36.0 | - |
| `cli-option.use-type-alias-type` | cli-option | `--use-type-alias-type` | 0.71.1 | - |
| `extra.httpx2` | extra | `datamodel-code-generator[httpx2]` | 0.71.1 | - |
| `formatter.builtin` | formatter | `--formatters builtin` | 0.59.0 | - |
| `input-format.asyncapi` | input-format | `--input-file-type asyncapi` | 0.59.0 | - |
| `input-format.avro` | input-format | `--input-file-type avro` | 0.59.0 | - |
| `input-format.mcp-tools` | input-format | `--input-file-type mcp-tools` | 0.60.0 | - |
| `input-format.protobuf` | input-format | `--input-file-type protobuf` | 0.59.0 | - |
| `input-format.xmlschema` | input-format | `--input-file-type xmlschema` | 0.59.0 | - |

## Details

### `behavior.batch-generation-jobs`

- **Kind:** behavior
- **Target:** `[tool.datamodel-codegen.jobs], --job, --all-jobs`
- **Since:** 0.72.3

Named batch jobs are experimental; their configuration schema, batch output, and transactional/watch execution contracts may change.

Define named generation jobs in [tool.datamodel-codegen.jobs] and select them with --job or --all-jobs. Each selected job has its own input and output, and the full selection is validated before generation begins.

### `behavior.remote-reference-lock`

- **Kind:** behavior
- **Target:** `datamodel-codegen.lock, --lockfile, --update-lock, and --locked`
- **Since:** 0.72.3

Remote reference integrity locking is experimental: the lock document schema and request-identity compatibility may evolve, but integrity mismatches remain fail-closed and credentials are never persisted.

The lock stores opaque SHA-256 request-identity digests and SHA-256 body digests, never response bodies or request values directly. Each saved display origin contains only the scheme, host, and explicit port—never a path, query, or request headers.

### `cli-option.generate-client`

- **Kind:** cli-option
- **Target:** `--generate-client httpx2 and the --client-* options (and their [tool.datamodel-codegen] keys and generate() options)`
- **Since:** 0.84.0

HTTPX2 client generation from the CLI is experimental; its options and generated package may change.

`--generate-client httpx2` generates the models at `--output` and a client package at `--client-output`; `--client-package` and `--client-model-package` name their import paths, and the other `--client-*` options configure the package. Like model options, they can be set in `[tool.datamodel-codegen]` of `pyproject.toml`, in its profiles, and in its jobs. `--check`, `--diff-against`, `--watch`, `--output-format json`, and the `uv add` and next-step notice on stderr work as with `--generate-server`. `generate()` takes them as `generate_client` and the `client_*` options, and returns every generated file without an output. It needs Python 3.11 or later, both to run and as `--target-python-version`, `--use-missing-sentinel` for `pydantic_v2.dataclass` models, `--target-pydantic-version 2.14` with `--use-missing-sentinel`, and `--use-msgspec-tagged-unions` and `--use-msgspec-nullable-enum-alias` for `msgspec.Struct` models; one left unset takes that value, as with `--generate-server`.

### `cli-option.generate-schema-validators`

- **Kind:** cli-option
- **Target:** `--generate-schema-validators`
- **Since:** 0.66.1

Schema-derived runtime validators are experimental and may change as JSON Schema coverage is expanded.

The option currently targets Pydantic v2 BaseModel output and covers selected object-level rules such as patternProperties, required-only oneOf/anyOf/not groups, and simple if/then/else required-property conditions.

### `cli-option.generate-server`

- **Kind:** cli-option
- **Target:** `--generate-server fastapi and the --server-* options (and their [tool.datamodel-codegen] keys and generate() options)`
- **Since:** 0.84.0

FastAPI server generation from the CLI is experimental; its options and generated package may change.

`--generate-server fastapi` generates the models at `--output` and a server package at `--server-output`, whose `main.py` serves the application with the implementations in the `services` package beside it; generation writes each missing module of `services` once, with stubs, and never overwrites one. `--server-package` and `--server-model-package` name their import paths, and the other `--server-*` options configure the package. Like model options, they can be set in `[tool.datamodel-codegen]` of `pyproject.toml`, in its profiles, and in its jobs. `--check` compares without writing, `--diff-against` compares the files two inputs render, `--watch` regenerates after input changes, `--output-format json` uses the model generation, check, and input-diff payloads, and generation prints a `uv add` command and the next steps to stderr. `generate()` takes them as `generate_server` and the `server_*` options, and returns every generated file without an output, writing no stubs. It needs Python 3.11 or later, both to run and as `--target-python-version`, `--use-missing-sentinel` for `pydantic_v2.dataclass` models, `--target-pydantic-version 2.14` with `--use-missing-sentinel`, and `--openapi-scopes` with `api`. A setting left unset, by the options, `pyproject.toml`, `generate()`, and the preset, takes that value, and the command line prints how to set it; one set otherwise is refused.

### `cli-option.install-skill`

- **Kind:** cli-option
- **Target:** `--install-skill, --skill-scope, and --overwrite-skill`
- **Since:** 0.76.0

Bundled Agent Skill installation is experimental; supported clients, scopes, and installed skill contents may change.

Use --install-skill with codex or claude-code. --skill-scope selects a project or user installation, and --overwrite-skill safely replaces an existing regular skill directory.

### `cli-option.schema-validator-type`

- **Kind:** cli-option
- **Target:** `--schema-validator-type`
- **Since:** 0.66.1

Schema-derived runtime validator backend selection is experimental and may change as validation backends are added.

The only currently implemented backend is 'pydantic-v2', which preserves the existing generated Pydantic v2 validator behavior.

### `cli-option.use-missing-sentinel`

- **Kind:** cli-option
- **Target:** `--use-missing-sentinel`
- **Since:** 0.66.1

Pydantic MISSING sentinel output is experimental because it depends on pydantic.experimental.missing_sentinel, or on pydantic.MISSING for a 2.14 target.

The option requires Pydantic v2 BaseModel or dataclass output and a target Pydantic version that supports the MISSING sentinel. Server and client generation require it for Pydantic v2 dataclass output, and `--target-pydantic-version 2.14` with it.

### `cli-option.use-type-alias`

- **Kind:** cli-option
- **Target:** `--use-type-alias`
- **Since:** 0.36.0

Type alias output is experimental and may change as Python typing support evolves.

The option replaces root model classes with type aliases where possible. Pydantic v2 output may use TypeAliasType or Python 3.12 type statements depending on the target Python version.

### `cli-option.use-type-alias-type`

- **Kind:** cli-option
- **Target:** `--use-type-alias-type`
- **Since:** 0.71.1

Runtime TypeAliasType output is experimental and may change as Python typing support evolves.

The option implies --use-type-alias and selects TypeAliasType for Python 3.10 and 3.11. Python 3.12 and newer continue to use native type statements.

### `extra.httpx2`

- **Kind:** extra
- **Target:** `datamodel-code-generator[httpx2]`
- **Since:** 0.71.1

The HTTPX2-backed HTTP client is experimental and may change as compatibility is validated.

`datamodel-code-generator[http]` remains the stable HTTPX backend and is not deprecated; `datamodel-code-generator[httpx2]` is experimental. The default HTTP backend policy is auto: stable httpx is selected when its client module is installed, including when both pairs are installed, and experimental httpx2 is selected only when that module is absent. Use `--http-backend httpx2` or `HTTPBackend.HTTPX2` to require the experimental pair. Explicit selections and paired dependency errors do not fall back.

### `formatter.builtin`

- **Kind:** formatter
- **Target:** `--formatters builtin`
- **Since:** 0.59.0

The internal formatter is experimental and may change as generated-output coverage is expanded.

The formatter is designed for generated model modules and is not a general-purpose Python formatter.

### `input-format.asyncapi`

- **Kind:** input-format
- **Target:** `--input-file-type asyncapi`
- **Since:** 0.59.0

AsyncAPI input support is experimental and may change as real-world usage is validated.

The parser focuses on message payload model generation from AsyncAPI documents.

### `input-format.avro`

- **Kind:** input-format
- **Target:** `--input-file-type avro`
- **Since:** 0.59.0

Apache Avro schema input support is experimental and may change as real-world usage is validated.

The parser generates Python models from Avro schemas; it does not provide Avro runtime validation.

### `input-format.mcp-tools`

- **Kind:** input-format
- **Target:** `--input-file-type mcp-tools`
- **Since:** 0.60.0

MCP tool schema profile input support is experimental and may change as MCP schemas evolve.

The input is converted from MCP tool inputSchema/outputSchema entries into JSON Schema definitions before model generation.

### `input-format.protobuf`

- **Kind:** input-format
- **Target:** `--input-file-type protobuf`
- **Since:** 0.59.0

Protocol Buffers input support is experimental and may change as real-world usage is validated.

The parser generates Python models from .proto schemas; it does not provide protobuf runtime validation or gRPC code generation.

### `input-format.xmlschema`

- **Kind:** input-format
- **Target:** `--input-file-type xmlschema`
- **Since:** 0.59.0

XML Schema input support is experimental and may change as real-world usage is validated.

The parser focuses on model generation from XSD documents, not full XML instance validation.

---

# Frequently Asked Questions

Source: https://datamodel-code-generator.koxudaxi.dev/faq/

## 📋 Schema Handling

### 🔀 oneOf/anyOf generates unexpected Union types

When using `oneOf` or `anyOf`, the generated models may not match your expectations. Use `--union-mode` to control how unions are generated:

```bash
# Smart union (Pydantic v2 only) - validates against types in order
datamodel-codegen --union-mode smart --output-model-type pydantic_v2.BaseModel ...

# Left-to-right validation
datamodel-codegen --union-mode left_to_right ...
```

See [CLI Reference: `--union-mode`](cli-reference/model-customization.md#union-mode) for details.

### 🔗 allOf doesn't merge properties as expected

Control how `allOf` schemas merge fields:

```bash
# Merge only constraints (minItems, maxItems, pattern, etc.) - default
datamodel-codegen --allof-merge-mode constraints ...

# Merge constraints + annotations (default, examples)
datamodel-codegen --allof-merge-mode all ...

# Don't merge any fields
datamodel-codegen --allof-merge-mode none ...
```

When primitive `allOf` branches are merged, combining `number` and `integer`
produces `integer` in every merge mode. Numeric type arrays may also include
`null`; only types shared by every branch are retained, in their original order.
An empty numeric/null intersection raises a schema error.

See [CLI Reference: `--allof-merge-mode`](cli-reference/typing-customization.md#allof-merge-mode) for details.

📎 Related: [#399](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/399)

### 📁 How to generate from multiple schema files?

Use a directory as input, or use `$ref` to reference other files:

```bash
# Generate from directory containing multiple schemas
datamodel-codegen --input schemas/ --output models/
```

For schemas with remote cross-file `$ref`, install an HTTP extra:

```bash
pip install 'datamodel-code-generator[http]'
```

See [HTTP backend selection](#http-backend-selection) for the stable and
experimental choices.

📎 Related: [#215](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/215)

### 🔤 YAML bool keywords (YES, NO, true, false) in string enums

YAML 1.1 treats unquoted keywords like `YES`, `NO`, `on`, `off`, `true`, `false` as boolean values. This tool preserves them as strings to avoid unexpected conversions in schema contexts:

```yaml
# Input YAML
enum:
  - YES
  - NO
  - NOT_APPLICABLE
```

```python
# Generated code (strings preserved)
class MyEnum(Enum):
    YES = "YES"
    NO = "NO"
    NOT_APPLICABLE = "NOT_APPLICABLE"
```

This matches the expected behavior when `type: string` is specified in your schema. If you need the previous behavior where YAML bool keywords were converted to Python booleans, please [open an issue](https://github.com/datamodel-code-generator/datamodel-code-generator/issues) describing your use case.

📎 Related: [#1653](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/1653), [#1766](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/1766), [#2338](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/2338)

---

## 🔍 Type Checking

### ⚠️ mypy complains about Field constraints

If mypy reports errors about `conint`, `constr`, or other constrained types, use `--field-constraints` or `--use-annotated`:

```bash
# Use Field(..., ge=0) instead of conint(ge=0)
datamodel-codegen --field-constraints ...

# Use Annotated[int, Field(ge=0)]
datamodel-codegen --use-annotated ...
```

See [Field Constraints](field-constraints.md) for more information.

### 🤔 Type checker doesn't understand generated types

Ensure you're using the correct target Python version:

```bash
datamodel-codegen --target-python-version 3.11 ...
```

This affects type syntax generation (e.g., `list[str]` vs `List[str]`, `X | Y` vs `Union[X, Y]`).

---

## 🏷️ Field Naming

### 🚫 Property names conflict with Python reserved words

Properties like `class`, `from`, `import` are automatically renamed with a `field_` prefix. Control this behavior:

```bash
# Custom prefix (default: "field")
datamodel-codegen --special-field-name-prefix my_prefix ...

# Remove special prefix entirely
datamodel-codegen --remove-special-field-name-prefix ...
```

### 🔣 Field names have special characters

JSON/YAML property names with spaces, dashes, or special characters are converted to valid Python identifiers. An alias is automatically generated to preserve the original name:

```python
class Model(BaseModel):
    my_field: str = Field(..., alias="my-field")
```

To disable aliases:

```bash
datamodel-codegen --no-alias ...
```

See [Field Aliases](aliases.md) for custom alias mappings.

### 🐍 Want snake_case field names from camelCase

```bash
datamodel-codegen --snake-case-field ...
```

This generates snake_case field names with camelCase aliases:

```python
class User(BaseModel):
    first_name: str = Field(..., alias="firstName")
```

---

## 🔄 Output Stability

### ⏰ Generated output changes on every run

The timestamp in the header changes on each run. Disable it for reproducible output:

```bash
datamodel-codegen --disable-timestamp ...
```

### 🌍 Output differs between environments

Ensure consistent formatting across environments:

```bash
# Explicitly set formatters
datamodel-codegen --formatters black isort ...

# Or disable formatting entirely for raw output
datamodel-codegen --formatters ...
```

Also ensure the same Python version and formatter configurations (`pyproject.toml`) are used.

### 🤖 CI fails because generated code is different

Use `--check` mode in CI to verify generated files are up-to-date:

```bash
datamodel-codegen --check --input schema.yaml --output models.py
```

This exits with code 1 if the output would differ, without modifying files.

### 🧹 Files from earlier runs remain in the output directory

Generation overwrites the files it writes and never deletes a file an earlier run wrote. Remove files that are no
longer generated yourself; `--check` of a directory output lists them as `EXTRA`.

A stale package can hide a new module. When a schema change turns a package of a directory output into a module, for
example `models/pets/` into `models/pets.py`, or a directory output `models/` gives way to a single-file output
`models.py`, the old directory stays, and Python imports a directory that holds an `__init__.py` in preference to the
module of the same name. Generation still writes the module and warns that the existing package directory shadows it,
naming both paths; remove the stale directory. A directory whose only `__init__` is a compiled `__init__.pyc` or an
extension module hides the module in the same way but is not reported. `--check` and `--diff-against` write nothing
and do not warn. `--disable-warnings` and Python warning filters silence the warning; a filter that turns it into an
error, such as `-W error::UserWarning`, stops the run before it writes anything.

---

## ⚡ Performance

### 🐢 Generation is slow for large schemas

For very large schemas with many models:

1. Use `--reuse-model` to deduplicate identical models
2. Consider splitting schemas into multiple files
3. Use `--disable-warnings` to reduce output

```bash
datamodel-codegen --reuse-model --disable-warnings ...
```

See [Model Reuse and Deduplication](model-reuse.md) for details.

---

## 🔧 Output Model Types

### 🤷 Which output model type should I use?

- **Pydantic v2** (`pydantic_v2.BaseModel`): ✨ Recommended for new projects. Better performance and modern API.
- **dataclasses**: Simple data containers without validation.
- **TypedDict**: Type hints for dict structures.
- **msgspec**: High-performance serialization.

See [Output Model Types](output-model-types.md) for a detailed comparison.

```bash
# For new projects
datamodel-codegen --output-model-type pydantic_v2.BaseModel ...
```

See [Output Model Types](output-model-types.md) for more details.

📎 Related: [#803](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/803)

### 💥 Generated code doesn't work with my Pydantic version

Ensure the output model type matches your installed Pydantic version:

```bash
# Check your Pydantic version
python -c "import pydantic; print(pydantic.VERSION)"

# Generate for Pydantic v2
datamodel-codegen --output-model-type pydantic_v2.BaseModel ...
```

---

## 🌐 Remote Schemas

### 📡 Cannot fetch schema from URL

Install the HTTP extra:

```bash
pip install 'datamodel-code-generator[http]'
```

The `http` extra is the stable choice. See
[HTTP backend selection](#http-backend-selection) if you want to use the
experimental HTTPX2 backend.

For authenticated endpoints:

```bash
datamodel-codegen --url https://api.example.com/schema.yaml \
    --http-headers "Authorization: Bearer TOKEN" \
    --output model.py
```

### 🔄 Which HTTP client backend is selected? {#http-backend-selection}

The HTTP extras install separate, matched client and transport stacks:

| Extra | Status | Client and transport |
|-------|--------|----------------------|
| `datamodel-code-generator[http]` | Stable, supported, and not deprecated | `httpx` + `httpcore` |
| `datamodel-code-generator[httpx2]` | Experimental | `httpx2` + `httpcore2` |

`datamodel-code-generator[all]` includes the stable `http` extra but
intentionally does not include the experimental `httpx2` extra.

Select the backend with `--http-backend {auto,httpx,httpx2}`, the corresponding
`http_backend` pyproject setting, or `HTTPBackend` in the public API:

1. `auto` is the default. It selects stable `httpx` when its client module is
   installed, including when both pairs are installed.
2. `auto` uses experimental `httpx2` + `httpcore2` only when the stable HTTPX
   client itself is unavailable.
3. `httpx` and `httpx2` require the selected pair. Explicit selections never
   fall back to a different backend.
4. A missing paired transport or another broken dependency in a selected stack
   raises its import error instead of hiding an invalid environment.
5. If `auto` finds neither client, the request fails with instructions to
   install an HTTP extra.

Selection and imports are lazy. Once `auto` selects a backend, it keeps that
selection for the process. Restart the process to change an already selected
backend after installing or removing an extra.

```toml title="pyproject.toml"
[tool.datamodel-codegen]
http-backend = "httpx2"
```

### 🔒 SSL certificate errors

For development/testing with self-signed certificates:

```bash
datamodel-codegen --url https://... --http-ignore-tls --output model.py
```

!!! warning "⚠️ Security Notice"
    Only use `--http-ignore-tls` in trusted environments.

---

## 📘 OpenAPI Specific

### 🌐 How can I request another HTTP library for generated API clients?

The experimental [Python client](python-client.md), generated with `--generate-client httpx2`, uses HTTPX2 for both
synchronous and asynchronous requests. If you need `aiohttp` or another HTTP library,
check [existing issues](https://github.com/datamodel-code-generator/datamodel-code-generator/issues), then
[start a discussion](https://github.com/datamodel-code-generator/datamodel-code-generator/discussions)
if your use case is not covered. Include the library you need, your use case, and whether you need synchronous
or asynchronous support. For performance-related requests, include a reproducible benchmark and the Python
and library versions.

This concerns requests made by generated API clients. [HTTP backend selection](#http-backend-selection)
controls fetching remote schemas during generation.

### 📝 How to handle readOnly/writeOnly properties?

Use `--read-only-write-only-model-type` to generate separate Request/Response models:

```bash
# Generate Request/Response models only
datamodel-codegen --read-only-write-only-model-type request-response ...

# Generate Base + Request + Response models
datamodel-codegen --read-only-write-only-model-type all ...
```

📎 Related: [#727](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/727)

### ❓ Why are nullable fields not Optional?

Use `--strict-nullable` to treat nullable fields as truly optional:

```bash
datamodel-codegen --strict-nullable ...
```

📎 Related: [#327](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/327)

---

## 🔧 Advanced

### 📦 How to use TypeAlias instead of RootModel?

Use `--use-type-alias` (experimental) to generate type aliases instead of root models:

```bash
datamodel-codegen --use-type-alias --output-model-type pydantic_v2.BaseModel ...
```

See [Root Models and Type Aliases](root-model-and-type-alias.md) for details.

📎 Related: [#2505](https://github.com/datamodel-code-generator/datamodel-code-generator/issues/2505)

---

## 📖 See Also

- 🖥️ [CLI Reference](cli-reference/index.md) - Complete option documentation
- ⚙️ [pyproject.toml Configuration](pyproject_toml.md) - Configure options via file
- 🐛 [GitHub Issues](https://github.com/datamodel-code-generator/datamodel-code-generator/issues) - Report bugs or request features
- 💬 [Discussions](https://github.com/datamodel-code-generator/datamodel-code-generator/discussions) - Ask questions and share ideas

---

# Architecture

Source: https://datamodel-code-generator.koxudaxi.dev/architecture/

`datamodel-code-generator` is organized around one central idea: many input formats are normalized into a shared
generation graph, then rendered through output-model-specific backends.

This page is partly generated from source code. The generated inventory is intentionally small so the narrative can stay
hand-written while release-time details such as parser routes and output backends stay synchronized.

## Generation Pipeline

```mermaid
flowchart TD
    subgraph entry["Entry points"]
        direction TB
        cli["CLI\n__main__.py"]
        api["Python API\ngenerate()"]
    end

    subgraph setup["Configuration and input handling"]
        direction TB
        config["GenerateConfig\nParserConfig"]
        normalize["Input normalization\ninfer / fetch / convert"]
    end

    subgraph parsing["Parsing"]
        direction TB
        parser["Parser.parse()"]
        raw["parse_raw()\nformat-specific parser"]
        model_graph["Generation graph\nDataModel / DataType / Reference"]
    end

    subgraph rendering["Rendering"]
        direction TB
        render["Templates\nmodel/template"]
        format["CodeFormatter"]
        output["Python files\nstdout / return value"]
    end

    cli --> api --> config --> normalize --> parser
    parser --> raw --> model_graph
    parser --> model_graph
    model_graph --> render --> format --> output
```

The CLI builds a `Config` from command-line arguments, `pyproject.toml`, and presets. It then calls the same
`generate()` API that library users can call directly. `generate()` selects the parser, runs it, and either returns code
or writes files.

## Entry Points

The executable entry point is defined in `pyproject.toml`:

```toml
datamodel-codegen = "datamodel_code_generator.__main__:main"
```

`src/datamodel_code_generator/__main__.py` owns CLI-only behavior:

- fast paths for `--version`, `--help`, prompt helpers, and JSON Schema output
- argument parsing and shell completion
- `pyproject.toml` profile loading and inheritance
- `--check` diff generation
- `--watch` regeneration
- structured JSON command output
- `--input-model` loading before normal generation

`src/datamodel_code_generator/__init__.py` owns the public generation API:

- `generate()`
- input type inference
- raw JSON/YAML/CSV/Dict conversion through genson
- MCP tool schema conversion
- parser construction
- generated headers and output file writing
- optional model metadata emission

## Parser Model

Each parser turns its input into `DataModel` objects. The parser-specific part is `parse_raw()`. The shared part is
`Parser.parse()`, which handles sorting, module layout, imports, rendering, exports, formatting, and optional metadata.

```mermaid
flowchart TD
    parse["Parser.parse()"]
    raw["parse_raw()\nimplemented by subclasses"]
    sort["sort_data_models()"]
    modules["_build_module_structure()"]
    process["_process_single_module()"]
    render["_generate_module_output()"]
    metadata["_build_model_metadata()"]
    result["str or module map"]

    parse --> raw --> sort --> modules --> process --> render --> metadata --> result
```

JSON Schema is the main reusable parser surface. OpenAPI and AsyncAPI extend it. Avro, XML Schema, Protocol Buffers,
raw data, and MCP tools convert to a JSON Schema-shaped document before using the same model-building machinery.
GraphQL is the main parser that builds models directly from its own schema API.

Ordering and module splitting use small graph helpers. `parser/_scc.py` finds strongly connected components with an
iterative Tarjan traversal so large graphs do not hit Python recursion limits. `parser/_graph.py` provides stable
topological ordering. Together they keep `sort_data_models()` deterministic and let `_build_module_structure()` move
circular module SCCs into `_internal.py` forwarder modules when imports would otherwise cycle.

## Generated Inventory

<!-- BEGIN AUTO-GENERATED ARCHITECTURE INVENTORY -->
!!! note "Generated inventory"
    This section is generated by `scripts/build_architecture_docs.py` from the current source tree.
    Edit the surrounding prose by hand, then run the script before release.

### Parser Inheritance

```mermaid
classDiagram
    JsonSchemaParser <|-- AvroParser
    JsonSchemaParser <|-- OpenAPIParser
    JsonSchemaParser <|-- ProtobufParser
    JsonSchemaParser <|-- XMLSchemaParser
    OpenAPIParser <|-- ApiOpenAPIParser
    OpenAPIParser <|-- AsyncAPIParser
    Parser <|-- GraphQLParser
    Parser <|-- JsonSchemaParser
```

### Input Routes

| Input file type | Parser route | Notes |
| --- | --- | --- |
| `auto` | `pre-parser inference` | Resolved before parser selection by content inference. |
| `openapi` | `OpenAPIParser` | Routed directly by `_build_parser()`. |
| `asyncapi` | `AsyncAPIParser` | Routed directly by `_build_parser()`. |
| `jsonschema` | `JsonSchemaParser` | Routed directly by `_build_parser()`. |
| `mcp-tools` | `JsonSchemaParser after conversion` | MCP tool input/output schemas are hoisted into JSON Schema definitions first. |
| `xmlschema` | `XMLSchemaParser` | Routed directly by `_build_parser()`. |
| `protobuf` | `ProtobufParser` | Routed directly by `_build_parser()`. |
| `avro` | `AvroParser` | Routed directly by `_build_parser()`. |
| `json` | `JsonSchemaParser after conversion` | Sample data is converted to JSON Schema with genson first. |
| `yaml` | `JsonSchemaParser after conversion` | Sample data is converted to JSON Schema with genson first. |
| `dict` | `JsonSchemaParser after conversion` | In-memory mapping is converted to JSON Schema with genson first. |
| `csv` | `JsonSchemaParser after conversion` | The header and first data row are converted to JSON Schema with genson first. |
| `graphql` | `GraphQLParser` | Routed directly by `_build_parser()`. |

### Output Backends

| Output model type | Data model | Root model | Field model | Type manager |
| --- | --- | --- | --- | --- |
| `pydantic_v2.BaseModel` | `model.pydantic_v2.base_model.BaseModel` | `model.pydantic_v2.root_model.RootModel` | `model.pydantic_v2.base_model.DataModelField` | `model.pydantic_v2.types.DataTypeManager` |
| `pydantic_v2.dataclass` | `model.pydantic_v2.dataclass.DataClass` | `model.type_alias.TypeAliasTypeBackport` | `model.pydantic_v2.dataclass.DataModelField` | `model.pydantic_v2.types.DataTypeManager` |
| `dataclasses.dataclass` | `model.dataclass.DataClass` | `model.type_alias.TypeAlias` | `model.dataclass.DataModelField` | `model.dataclass.DataTypeManager` |
| `typing.TypedDict` | `model.typed_dict.TypedDict` | `model.type_alias.TypeAlias` | `model.typed_dict.DataModelFieldBackport` | `model.types.DataTypeManager` |
| `msgspec.Struct` | `model.msgspec.Struct` | `model.type_alias.TypeAlias` | `model.msgspec.DataModelField` | `model.msgspec.DataTypeManager` |

### Configuration Surface

| Config model | Field count | Purpose |
| --- | ---: | --- |
| `BaseGenerateConfig` | 179 | Shared generation options. |
| `GenerateConfig` | 194 | Public `generate()` configuration. |
| `ParserConfig` | 145 | Base parser dependency injection and parser options. |
| `JSONSchemaParserConfig` | 147 | JSON Schema parser options. |
| `OpenAPIParserConfig` | 153 | OpenAPI-specific parser options. |
| `AsyncAPIParserConfig` | 154 | AsyncAPI-specific parser options. |
| `XMLSchemaParserConfig` | 148 | XML Schema-specific parser options. |
| `ProtobufParserConfig` | 148 | Protocol Buffers-specific parser options. |
| `AvroParserConfig` | 147 | Avro-specific parser options. |
| `GraphQLParserConfig` | 148 | GraphQL-specific parser options. |

### Formatter Names

| Formatter | Default when unspecified |
| --- | --- |
| `builtin` | no |
| `black` | yes |
| `isort` | yes |
| `ruff-check` | no |
| `ruff-format` | no |
<!-- END AUTO-GENERATED ARCHITECTURE INVENTORY -->

## Intermediate Model Graph

The generation graph is built from a small set of core objects:

- `DataModel`: a generated class, root model, type alias, enum, scalar alias, or union alias.
- `DataModelFieldBase`: one field on a generated model, including defaults, aliases, constraints, and metadata.
- `DataType`: a Python type annotation tree, including containers, unions, literals, generated-model references, and
  imports.
- `Reference`: a schema reference path and generated Python name.
- `GenerationStore`: the parser-owned model list plus a query index over model and type dependencies.

```mermaid
classDiagram
    class Parser
    class GenerationStore
    class GenerationIndex
    class ModelResolver
    class DataModel
    class DataModelFieldBase
    class DataType
    class Reference

    Parser --> GenerationStore
    Parser --> ModelResolver
    GenerationStore --> GenerationIndex
    GenerationStore --> DataModel
    DataModel --> DataModelFieldBase
    DataModelFieldBase --> DataType
    DataModel --> Reference
    DataType --> Reference
    ModelResolver --> Reference
```

`GenerationStore` is the preferred mutation boundary for parser-side changes that affect dependency facts. Parser code
should register models and update references, fields, bases, names, and paths through store methods instead of mutating
the live objects directly. `GenerationIndex` rebuilds stable facts from the model list and gives later phases efficient
queries such as "which data types point at this reference?".

## References And Names

`ModelResolver` is the naming and reference authority. It tracks the current root, base path, base URL, root IDs, and
known references while parsers traverse documents. It also applies naming options such as aliases, `model_name_map`,
prefixes, suffixes, duplicate suffixes, enum member normalization, and field name safety.

`Reference.children` still links references back to users, but newer parser post-processing should prefer
`GenerationIndex` when it needs dependency facts. The index is rebuilt from live models and avoids depending on legacy
side effects alone.

## Output Backends

Parsers do not hard-code Pydantic, dataclass, TypedDict, or msgspec classes. `get_data_model_types()` returns a
`DataModelSet` for the selected `DataModelType`. That set injects:

- the model class
- the root model or type alias class
- the field class
- the type manager
- optional reference dumping behavior
- GraphQL scalar and union model classes

The same parser output can therefore render into different Python model styles while sharing the same reference and
module-generation pipeline.

## Layer Dependency Rules

The pipeline is also a dependency boundary. Configuration and entry points select behavior, parsers normalize source
formats, and output models own rendering-framework behavior. Keep these rules when adding features or optimizing hot
paths:

- Parser modules may depend on neutral `DataModel`, `DataModelFieldBase`, and declared capability hooks. They must not
  import or identify concrete Pydantic, dataclass, TypedDict, or msgspec output implementations.
- Output-specific constructor, forward-reference, runtime-validation, import-conflict, and rendering behavior belongs
  to the output model that implements it. The parser calls the neutral capability without switching on backend names.
  This includes annotation representation, TypedDict provider selection, configuration assembly, and access to
  prepared output metadata. Existing custom-template keys and extension capabilities remain compatibility contracts;
  moving their preparation between layers must preserve generated code, insertion order, and option precedence.
- Output models inject reserved-field and generated-import conflict handling through `FIELD_NAME_RESOLVER_CLASS`;
  `ModelResolver` owns only neutral normalization and lazily creates the selected resolver.
  Legacy resolver imports and default `ModelResolver` policies resolve those output-owned providers lazily.
- Reusable graph, detection, enum, cache, JSON Schema reference rewriting, and parser retry-signal helpers belong in
  neutral package modules. Code outside `parser/` must not import private parser modules or private symbols from public
  parser modules, such as `parser.mcp._rewrite_schema_refs`.
- Input-model conversion reads output-family compatibility from the output selection registry. It must not maintain a
  second `DataModelType`-to-backend mapping.
- Input-model build tokens must resolve to neutral `input_model_result` schema annotations before parser construction.
  Parsers consume that IR and must not import the private input-model transport. The former token table and parser
  factory remain lazy private compatibility paths and are not allocated by normal generation.
- Configuration must not acquire new parser or concrete output-backend dependencies. Historical concrete defaults are
  narrowly allowlisted until they can be migrated without changing the public `ParserConfig` surface.
- Entry points project source and reference settings into a frozen `ParserSourceContext` attached to their lightweight,
  already-validated config; direct parser APIs retain typed configuration and validation.

Run `python scripts/check_architecture_boundaries.py` to validate these rules. The checker parses imports and semantic
backend inspection with the Python AST, including lazy and dynamic imports. Entrypoint, parser, configuration,
input-model, reference, model-composition, output-model, and shared-model files are classified explicitly. The
composition root may select concrete backends, while shared-model modules must remain neutral: they cannot import a
concrete backend or resolve one through `sys.modules`, including module-name constants and aliases. This keeps
backend-specific lifecycle and cache ownership with the backend or composition root, without blocking neutral module
registry access such as `sys.modules[model_type.__module__]`. Private parser lifecycle access and reference-owned
backend policy therefore cannot hide in the shared layer. Its legacy allowlist is keyed by file, enclosing symbol, rule,
and target; extra occurrences fail, and removed dependencies make stale entries fail so the exception cannot silently
become permanent. The same check runs in pre-commit and pytest with actionable diagnostics.

## Rendering And Formatting

Every `DataModel` renders through a Jinja2 template. Built-in templates live in
`src/datamodel_code_generator/model/template`. A custom template directory can override a built-in template by path.

Imports are collected separately from rendering through `Import` and `Imports`. The import layer handles grouping,
aliases, reference-bound imports, future imports, unused import removal, and `__all__` generation.

`CodeFormatter` then applies the configured formatter pipeline. The formatter layer supports the built-in formatter,
black, isort, ruff check, ruff format, and user-supplied custom formatters.

## Metadata Output

When `--emit-model-metadata` is enabled, `Parser.parse()` records source-reference information while producing models.
`generate()` then serializes the resulting payload through `model_metadata.py`. The JSON Schema for that payload is
stored in `src/datamodel_code_generator/resources/model_metadata.schema.json` and exposed through
`--output-format-json-schema model-metadata`.

## Runtime Dynamic Models

`generate_dynamic_models()` uses the normal `generate()` API to produce code, executes that code in temporary modules,
and returns real Pydantic v2 model classes. Multi-module output is topologically sorted by relative imports before
execution. The result is cached by schema and config hash when caching is enabled.

## Performance-Sensitive Paths

Recent work has focused on reducing work without changing the generation model:

- fast CLI paths avoid importing heavy modules
- `format.py` keeps format-related types in a lighter helper module
- local schema sources are reused during `$ref` resolution
- YAML unsupported-tag scanning is skipped when no unsupported tag marker is present
- JSON Schema constraint extraction avoids dumping whole schema objects when only selected constraint keys are needed
- simple field import collection avoids rendering a full type hint when `DataType` facts are sufficient

These optimizations keep the architecture stable: parsers still build the same graph, and renderers still produce the
same code, but hot paths do less incidental work.

## Keeping This Page Synchronized

Run this before release or whenever parser routes, output backends, config models, or formatter names change:

```bash
python scripts/build_architecture_docs.py
```

CI can validate the generated section without rewriting files:

```bash
python scripts/build_architecture_docs.py --check
```

The repository test suite includes this check through `tests/test_build_architecture_docs_script.py`, so pull requests
fail when the generated inventory is stale. The `generated-docs` tox environment also runs this script before
`build_llms_txt.py`, which keeps the architecture page and LLM documentation in the same release-time sync flow.

---

# Development

Source: https://datamodel-code-generator.koxudaxi.dev/development-contributing/

Install the package in editable mode:

```sh
$ git clone git@github.com:datamodel-code-generator/datamodel-code-generator.git
$ pip install -e datamodel-code-generator
```

# 🤝 Contribute

We are waiting for your contributions to `datamodel-code-generator`.

## 📝 How to contribute

```bash
## 1. Clone your fork repository
$ git clone git@github.com:<your username>/datamodel-code-generator.git
$ cd datamodel-code-generator

## 2. Install [uv](https://docs.astral.sh/uv/getting-started/installation/)
$ curl -LsSf https://astral.sh/uv/install.sh | sh

## 3. Install tox with uv
$ uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv

## 4. Create developer environment
$ tox run -e dev

.tox/dev is a Python environment you can use for development purposes

## 5. Install pre-commit hooks
$ uv tool install prek
$ prek install

## 6. Create new branch and rewrite code.
$ git checkout -b new-branch

## 7. Run unittest under Python 3.13 (you should pass all test and coverage should be 100%)
$ tox run -e 3.13

## 8. Format and lint code (will print errors that cannot be automatically fixed)
$ tox run -e fix

## 9. Check generated docs, diagrams, and playground assets are up to date
$ tox run -e docs-check-all -- --check

## 10. Commit and Push...
```

## 🧪 E2E test assertions

E2E tests that validate generated output must use the shared assertion helpers
instead of direct `assert` statements. The helpers compare complete generated
files, generated modules, warnings, errors, and HTTP request behavior with
consistent diffs and update hints.

Use helpers such as `run_main_and_assert`, `run_main_url_and_assert`,
`create_assert_file_content`, `assert_output`, `assert_directory_content`,
`assert_generated_modules_output`, `assert_generated_file_matches_output`,
`assert_httpx_get_kwargs`, and `assert_warnings_contain` where they fit. Prefer
full expected-file or inline snapshot comparisons for generated output over
substring checks.

The file-output helpers use
[`inline-snapshot`](https://15r10nk.github.io/inline-snapshot/latest/) and
`external_file()` internally. When an expected output file is missing, the
failure message includes the command to create it, such as
`tox run -e <version> -- --inline-snapshot=create`. When an existing expected
file differs from the generated output, the failure includes a diff and the
command to update it, such as
`tox run -e <version> -- --inline-snapshot=fix`. Review the generated files and
the resulting `git diff` before committing. See the inline-snapshot
[`--inline-snapshot` pytest options](https://15r10nk.github.io/inline-snapshot/latest/pytest/#-inline-snapshotcreatefixtrimupdate)
for the meaning of `create` and `fix`.

Direct `assert` statements are blocked in guarded test modules by
`tests/test_assert_helper_usage.py`. New test files are guarded by default; add
legacy or unit-focused files to
`assert_helper_direct_assert_exempt_files` in `pyproject.toml` only when they
are intentionally outside the generated-output helper policy. Use
`@pytest.mark.allow_direct_assert` for narrow in-file exceptions that cannot
reasonably be expressed with the shared helpers, such as external-request mock
checks or intermediate-state checks.

## 🎯 Client and server target tests

Tests for the generated client and server (FastAPI) packages live in `tests/api_generation/`. The client runtime
scenarios, one module per behavior such as `client_retry_calls.py`, live in `tests/api_generation/scenarios/`, and
`test_client_runtime.py` drives them. The shared harness, fixture servers, and generation helpers live in
`tests/api_generation/support/`. The other `test_*.py` modules (client generation, CLI, typing, and the FastAPI
tests) keep their own cases and use `support/` for setup. Both directories are linted and covered like other tests,
except for the modules still listed in `[tool.coverage] run.omit` in `pyproject.toml`; issue
[#4572](https://github.com/koxudaxi/datamodel-code-generator/issues/4572) tracks removing those entries.

Tests go through the public `generate()` function or the `datamodel-codegen` CLI only. Do not assert on
internal objects, and use mocks only for abnormal paths (injected faults, marked with
`@pytest.mark.abnormal_path`) and external services.

A generated client copies the codec module of its own model backend only. The dataclass and TypedDict modules,
`_runtime/model_codecs/stdlib_dataclasses.py` and `stdlib_typeddicts.py`, are derived from `stdlib.py.jinja2` beside
them: edit that source and run `python scripts/build_stdlib_codecs.py`. Its `--check` option, which
`tests/model_codecs/test_wire_values.py` runs, fails when a module differs from what the source derives.

Expected output lives under `tests/data/expected/main/generation_platform/`:

- `client/packages/<case>/<backend>/` and `fastapi/packages/<case>/<backend>/` hold generated packages, including
  server `README.md` files where the case selects one.
- `client/bindings/<case>/<backend>/<variant>/client/_generated/model_bindings.py` pins the model bindings each
  case generates.
- `client/capabilities/*.txt` and the other `*.txt` reports list copied runtime modules by name. Line counts appear
  only in `minimal`. Each capability report also lists the modules the package imports from outside the standard
  library: those of the printed dependencies, then the others, which only those dependencies' own requirements may
  provide.
- `client/typing/dependencies/*.txt` hold the checkers' findings for a package of each backend where only its
  printed dependencies are installed.
- Reports hold listings, diagnostics, and outcomes. Generated source is pinned as files at its generated path, not
  embedded in a report.

Compare output with the helpers described under "E2E test assertions":
`assert_output` for reports, `assert_generated_modules_output` for `generate(output=None)` modules,
`assert_exact_directory_content` for trees written to disk, and `run_main_and_assert` for CLI runs. Regenerate
expected files by running the module with `-n0` and `--inline-snapshot=fix`. Under `pytest-xdist`, inline-snapshot
cannot create or fix files, but comparisons still run. `assert_exact_directory_content` has no snapshot indirection, so
pin trees it compares through a snapshot-backed helper or update them from the generated output, then review
`git diff`.

`tests/test_assert_helper_usage.py` guards these directories against direct asserts, unit-style checks, and
private imports. Its exceptions are listed in `tests/assert_helper_allowlists.py`. Those lists only shrink: remove
an entry when you fix its violation, and do not add new ones.

## Documentation formatting

Ruff formats Python code blocks in Markdown, including hand-written explanations.
Documentation builders surround fixture-backed examples and generated output with
`<!-- fmt: off -->` and `<!-- fmt: on -->` so the displayed code keeps the exact
quote style and layout produced by the documented command. Keep these markers in
the builders rather than editing generated Markdown directly.

After changing documentation, regenerate the affected pages and then run
`python scripts/build_llms_txt.py`. Run `tox run -e fix` and
`tox run -e docs-check-all -- --check` to verify formatting and generated content
agree.

## Release notes

Release notes should describe changes that affect users: features, fixes,
generated output, performance, compatibility, installation requirements, and
the official GitHub Action or Playground.

Use the `skip-changelog` PR label for changes that only maintain tests, CI,
release automation, generated documentation, or development tooling. The
release workflow adds it automatically when every changed file is a known
maintenance file, including CHANGELOG updates and release benchmark data.
Other changes need a maintainer's judgment before applying the label.

Check the complete diff before excluding dependency updates, refactors, or
documentation changes. They can affect users through `action.yml`, packaged
CLI prompt data, Playground assets, or generated code. A PR that mixes
maintenance with user-facing changes should stay in the release notes.

The label only filters GitHub's generated change list. Breaking-change
analysis still runs independently, and the full comparison link remains
available. Excluded PRs receive no release notification unless they are
referenced elsewhere in the release body.

## Architecture boundaries

Before adding a dependency between layers, check `docs/architecture.md` and run:

```bash
python scripts/check_architecture_boundaries.py
```

The guard rejects concrete output-backend imports and backend-name inspection in
parsers, concrete backend imports or `sys.modules` lookups from shared model
modules, private `parser._*` imports from shared code, parser/backend dependencies
from configuration, and local output-family mappings in `input_model.py`. Move
output behavior to a neutral capability on `DataModel` or `DataModelFieldBase`,
keep backend lifecycle and cache management with its backend or the model
composition root, and move reusable helpers to a neutral package module. Do not
add an allowlist entry for new code. Existing entries document compatibility debt,
have bounded occurrence counts, and fail when stale.

Tests for the checker use source fixtures and expected reports under
`tests/data/architecture_boundaries/` and
`tests/data/expected/architecture_boundaries/`. Keep diagnostics specific enough
that a contributor or coding agent can identify the owning layer and the expected
remediation without reading the checker implementation.

## Parser generation state

Parser code must keep generated output, naming order, parse order, and
canonical model selection compatible with existing releases. `ModelResolver`
remains the only authority for names. Do not move name generation or parser
dispatch into the generation index.

Use `GenerationStore` for parser-side mutations that affect generation facts:

- Register parsed models with `generation_store.register_model(model)`.
- Replace references with `generation_store.replace_data_type_ref(...)` or
  `generation_store.detach_data_type_ref(...)`.
- Replace field or nested data types with `replace_field_type(...)`,
  `replace_nested_data_type(...)`, or `set_nested_data_types(...)`.
- Replace fields or base classes with `set_fields(...)`,
  `append_field(...)`, `insert_field(...)`, `remove_field(...)`, or
  `set_base_classes(...)`.
- Move or rename generated models with `move_model(...)`,
  `rename_model(...)`, or `update_model_reference(...)`.

Parser code should not directly assign `data_type.reference`, `model.fields`,
`model.base_classes`, `model.reference.name`, or call reference child mutation
helpers. Read dependency information through `GenerationIndex` queries instead
of using `Reference.children` as a reverse index.

The local pre-commit hook `generation-store-usage` runs
`scripts/check_generation_store_usage.py` and rejects common parser mutations
that bypass the store. If a new mutation helper is needed, add the method to
`GENERATION_STORE_MUTATION_METHODS` and update the checker tests so contributors
get an actionable message.

## ➕ Adding a New CLI Option

When adding a new CLI option to `datamodel-code-generator`, follow these steps:

### Step 1: Implement the option (Required)

Add the option to `src/datamodel_code_generator/arguments.py`:

```python
arg_parser.add_argument(
    "--my-new-option",
    help="Description of what this option does",
    action="store_true",  # or other action type
)
```

### Step 2: Add a test with documentation marker (Required)

Create a test that demonstrates the option and add the `@pytest.mark.cli_doc()` marker:

```python
@pytest.mark.cli_doc(
    options=["--my-new-option"],
    input_schema="jsonschema/example.json",  # Path relative to tests/data/
    cli_args=["--my-new-option"],
    golden_output="jsonschema/example_with_my_option.py",  # Expected output
)
def test_my_new_option(output_file: Path) -> None:
    """Short description of what the option does.

    This docstring becomes the documentation for the option.
    Explain when and why users would use this option.
    """
    run_main_and_assert(
        input_path=JSON_SCHEMA_DATA_PATH / "example.json",
        output_path=output_file,
        extra_args=["--my-new-option"],
        ...
    )
```

### Step 3: Categorize the option (Optional)

By default, new options appear in "General Options". To place in a specific category, add to `src/datamodel_code_generator/cli_options.py`:

```python
CLI_OPTION_META: dict[str, CLIOptionMeta] = {
    ...
    "--my-new-option": CLIOptionMeta(
        name="--my-new-option",
        category=OptionCategory.MODEL,  # or FIELD, TYPING, TEMPLATE, etc.
    ),
}
```

### Step 4: Generate and verify documentation

```bash
# Regenerate CLI docs
$ pytest --collect-cli-docs -p no:xdist -q
$ python scripts/build_cli_docs.py

# Verify generated docs are correct
$ tox run -e docs-check-all -- --check

# If you modified config.py, regenerate config TypedDicts
$ tox run -e config-types
```

### 🔧 Troubleshooting

If the `tox run -e docs-check-all -- --check` CLI docs step fails:

- **"No test found documenting option --xxx"**: Add `@pytest.mark.cli_doc(options=["--xxx"], ...)` to a test
- **"File not found: ..."**: Check that `input_schema` and `golden_output` paths are correct
- **"CLI docs are OUT OF DATE"**: Run `python scripts/build_cli_docs.py` to regenerate

## 📖 CLI Documentation Marker Reference

The `cli_doc` marker supports:

| Parameter | Required | Description |
|-----------|----------|-------------|
| `options` | Yes | List of CLI options this test documents |
| `input_schema` | Yes | Input schema path (relative to `tests/data/`) |
| `cli_args` | Yes | CLI arguments used in the test |
| `golden_output` | Yes* | Expected output file path |
| `model_outputs` | No | Dict of model type → output file (for multi-model tabs) |
| `version_outputs` | No | Dict of Python version → output file |
| `comparison_output` | No | Baseline output without option (for before/after) |
| `primary` | No | Set `True` if this is the main example for the option |

*Either `golden_output` or `model_outputs` is required.

See existing tests in `tests/main/` for examples.

---
