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.
The official GitHub Action provides a simple way to validate generated models in your CI pipeline.
- uses: koxudaxi/datamodel-code-generator@0.44.0
with:
input: schema.yaml
output: src/models.py
input-file-type: openapi
output-model-type: pydantic_v2.BaseModelBy 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.
| 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, jsonschema, json, yaml, csv, graphql) |
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) |
name: Validate Generated Models
on:
pull_request:
paths:
- 'schemas/**'
- 'src/models/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: koxudaxi/datamodel-code-generator@0.44.0
with:
input: schemas/api.yaml
output: src/models/api.py
input-file-type: openapi
output-model-type: pydantic_v2.BaseModeljobs:
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: koxudaxi/datamodel-code-generator@0.44.0
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 }}- uses: koxudaxi/datamodel-code-generator@0.44.0
with:
input: schemas/api.yaml
output: src/models.py
input-file-type: openapi
output-model-type: pydantic_v2.BaseModel
profile: apiSet check: 'false' to actually generate the models:
- uses: koxudaxi/datamodel-code-generator@0.44.0
with:
input: schema.yaml
output: src/models.py
input-file-type: openapi
output-model-type: pydantic_v2.BaseModel
check: 'false'For GraphQL schemas, use the extras input to install the required dependency:
- uses: koxudaxi/datamodel-code-generator@0.44.0
with:
input: schema.graphql
output: src/models.py
input-file-type: graphql
output-model-type: pydantic_v2.BaseModel
extras: 'graphql'You can install multiple extras with comma-separated values:
- uses: koxudaxi/datamodel-code-generator@0.44.0
with:
input: schema.yaml
output: src/models.py
input-file-type: openapi
output-model-type: pydantic_v2.BaseModel
extras: 'http,validation,ruff'Use extra-args for CLI options not covered by the inputs:
- uses: koxudaxi/datamodel-code-generator@0.44.0
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., @0.44.0) to ensure reproducible builds. The action installs the same version of datamodel-code-generator as the tag.
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.
datamodel-codegen --checkWhen generated code matches the existing file, the command exits silently with code 0:
$ datamodel-codegen --check
$ echo $?
0When the schema has changed and the generated code would differ, a unified diff is shown and the command exits with code 1:
$ 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, --disable-timestamp, pyproject.toml Configuration
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 --checkFor projects with multiple schemas, use named profiles to organize configurations by purpose:
[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"- 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 --checkIf your project uses uv, you can run the CLI via uv run. This example installs the tool ephemerally (no need to add it to your project dependencies):
- 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 --checkYou can use datamodel-code-generator as a pre-commit 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.
Configure settings in pyproject.toml and use a simple pre-commit hook:
repos:
- repo: https://github.com/koxudaxi/datamodel-code-generator
rev: vX.Y.Z
hooks:
- id: datamodel-code-generator
args: [--check]
files: ^schemas/For projects with multiple schemas using named profiles:
repos:
- repo: https://github.com/koxudaxi/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/This configuration automatically regenerates models when schema files change:
repos:
- repo: https://github.com/koxudaxi/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
```
check-generated-code:
image: python:3.14
script:
- pip install datamodel-code-generator
- datamodel-codegen --check
rules:
- changes:
- schemas/**/*
- src/models/**/*Add targets to your Makefile for easy generation and checking:
.PHONY: generate-models check-models
generate-models:
datamodel-codegen
check-models:
datamodel-codegen --checkThen use in CI:
- name: Check generated models
run: make check-modelsFor projects with multiple profiles:
.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 --checkEnsure you're using the same formatters in CI as locally. Configure formatters in pyproject.toml:
[tool.datamodel-codegen]
formatters = ["ruff"]See Formatting for details.
Related: --formatters
Always use disable-timestamp = true in pyproject.toml:
[tool.datamodel-codegen]
disable-timestamp = trueRelated: --disable-timestamp
Some type annotations differ between Python versions. Pin the target version in pyproject.toml and ensure CI uses the same Python version as development:
[tool.datamodel-codegen]
target-python-version = "3.14"Related: --target-python-version