Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions docs/cli-reference/general-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
| [`--http-ignore-tls`](#http-ignore-tls) | Disable TLS certificate verification for HTTPS requests. |
| [`--http-query-parameters`](#http-query-parameters) | Add query parameters to HTTP requests for remote schemas. |
| [`--ignore-pyproject`](#ignore-pyproject) | Ignore pyproject.toml configuration file. |
| [`--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... |
| [`--watch`](#watch) | Watch mode cannot be used with --check mode. |
| [`--watch-delay`](#watch-delay) | Watch mode starts file watcher and handles clean exit. |
Expand Down Expand Up @@ -1672,6 +1673,116 @@ testing without project configuration.

---

## `--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`](general-options.md#all-exports-scope), [`--use-exact-imports`](template-customization.md#use-exact-imports)

!!! tip "Usage"

```bash
datamodel-codegen --input schema.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 "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"}
}
}
}
}
```

??? example "Output"

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


class Model(BaseModel):
__root__: Any

# order.py
# generated by datamodel-codegen:
# filename: input.json

from __future__ import annotations

from typing import Optional

from pydantic import BaseModel

from .user import User


class Order(BaseModel):
id: Optional[int] = None
user: Optional[User] = None

# user.py
# generated by datamodel-codegen:
# filename: input.json

from __future__ import annotations

from typing import Optional

from pydantic import BaseModel


class User(BaseModel):
id: Optional[int] = None
name: Optional[str] = None
```

---

## `--shared-module-name` {#shared-module-name}

Customize the name of the shared module for deduplicated models.
Expand Down
8 changes: 6 additions & 2 deletions docs/cli-reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ This documentation is auto-generated from test cases.
| 🏗️ [Model Customization](model-customization.md) | 26 | Model generation behavior |
| 🎨 [Template Customization](template-customization.md) | 16 | Output formatting and custom rendering |
| 📘 [OpenAPI-only Options](openapi-only-options.md) | 5 | OpenAPI-specific features |
| ⚙️ [General Options](general-options.md) | 13 | Utilities and meta options |
| ⚙️ [General Options](general-options.md) | 14 | Utilities and meta options |
| 📝 [Utility Options](utility-options.md) | 5 | Help, version, debug options |

## All Options

**Jump to:** [A](#a) · [B](#b) · [C](#c) · [D](#d) · [E](#e) · [F](#f) · [G](#g) · [H](#h) · [I](#i) · [K](#k) · [N](#n) · [O](#o) · [P](#p) · [R](#r) · [S](#s) · [T](#t) · [U](#u) · [V](#v) · [W](#w)
**Jump to:** [A](#a) · [B](#b) · [C](#c) · [D](#d) · [E](#e) · [F](#f) · [G](#g) · [H](#h) · [I](#i) · [K](#k) · [M](#m) · [N](#n) · [O](#o) · [P](#p) · [R](#r) · [S](#s) · [T](#t) · [U](#u) · [V](#v) · [W](#w)


### A {#a}
Expand Down Expand Up @@ -102,6 +102,10 @@ This documentation is auto-generated from test cases.
- [`--keep-model-order`](model-customization.md#keep-model-order)
- [`--keyword-only`](model-customization.md#keyword-only)

### M {#m}

- [`--module-split-mode`](general-options.md#module-split-mode)

### N {#n}

- [`--no-alias`](field-customization.md#no-alias)
Expand Down
2 changes: 2 additions & 0 deletions docs/cli-reference/quick-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ datamodel-codegen [OPTIONS]
| [`--http-ignore-tls`](general-options.md#http-ignore-tls) | Disable TLS certificate verification for HTTPS requests. |
| [`--http-query-parameters`](general-options.md#http-query-parameters) | Add query parameters to HTTP requests for remote schemas. |
| [`--ignore-pyproject`](general-options.md#ignore-pyproject) | Ignore pyproject.toml configuration file. |
| [`--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. |
| [`--watch`](general-options.md#watch) | Watch mode cannot be used with --check mode. |
| [`--watch-delay`](general-options.md#watch-delay) | Watch mode starts file watcher and handles clean exit. |
Expand Down Expand Up @@ -214,6 +215,7 @@ All options sorted alphabetically:
- [`--input-file-type`](base-options.md#input-file-type) - Specify the input file type for code generation.
- [`--keep-model-order`](model-customization.md#keep-model-order) - Keep model definition order as specified in schema.
- [`--keyword-only`](model-customization.md#keyword-only) - Generate dataclasses with keyword-only fields (Python 3.10+)...
- [`--module-split-mode`](general-options.md#module-split-mode) - Split generated models into separate files, one per model cl...
- [`--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-use-specialized-enum`](typing-customization.md#no-use-specialized-enum) - Disable specialized Enum classes for Python 3.11+ code gener...
Expand Down
12 changes: 12 additions & 0 deletions src/datamodel_code_generator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,15 @@ class ReadOnlyWriteOnlyModelType(Enum):
All = "all"


class ModuleSplitMode(Enum):
"""Mode for splitting generated models into separate files.

Single: Generate one file per model class.
"""

Single = "single"


class Error(Exception):
"""Base exception for datamodel-code-generator errors."""

Expand Down Expand Up @@ -470,6 +479,7 @@ def generate( # noqa: PLR0912, PLR0913, PLR0914, PLR0915
read_only_write_only_model_type: ReadOnlyWriteOnlyModelType | None = None,
all_exports_scope: AllExportsScope | None = None,
all_exports_collision_strategy: AllExportsCollisionStrategy | None = None,
module_split_mode: ModuleSplitMode | None = None,
) -> None:
"""Generate Python data models from schema definitions or structured data.

Expand Down Expand Up @@ -718,6 +728,7 @@ def get_header_and_first_line(csv_file: IO[str]) -> dict[str, Any]:
disable_future_imports=disable_future_imports,
all_exports_scope=all_exports_scope,
all_exports_collision_strategy=all_exports_collision_strategy,
module_split_mode=module_split_mode,
)
if not input_filename: # pragma: no cover
if isinstance(input_, str):
Expand Down Expand Up @@ -857,6 +868,7 @@ def infer_input_type(text: str) -> InputFileType:
"InputFileType",
"InvalidClassNameError",
"LiteralType",
"ModuleSplitMode",
"PythonVersion",
"ReadOnlyWriteOnlyModelType",
"generate",
Expand Down
3 changes: 3 additions & 0 deletions src/datamodel_code_generator/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
Error,
InputFileType,
InvalidClassNameError,
ModuleSplitMode,
OpenAPIScope,
ReadOnlyWriteOnlyModelType,
ReuseScope,
Expand Down Expand Up @@ -464,6 +465,7 @@ def validate_all_exports_collision_strategy(cls, values: dict[str, Any]) -> dict
read_only_write_only_model_type: Optional[ReadOnlyWriteOnlyModelType] = None # noqa: UP045
all_exports_scope: Optional[AllExportsScope] = None # noqa: UP045
all_exports_collision_strategy: Optional[AllExportsCollisionStrategy] = None # noqa: UP045
module_split_mode: Optional[ModuleSplitMode] = None # noqa: UP045
watch: bool = False
watch_delay: float = 0.5

Expand Down Expand Up @@ -765,6 +767,7 @@ def run_generate_from_config( # noqa: PLR0913, PLR0917
read_only_write_only_model_type=config.read_only_write_only_model_type,
all_exports_scope=config.all_exports_scope,
all_exports_collision_strategy=config.all_exports_collision_strategy,
module_split_mode=config.module_split_mode,
)


Expand Down
7 changes: 7 additions & 0 deletions src/datamodel_code_generator/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
DataclassArguments,
DataModelType,
InputFileType,
ModuleSplitMode,
OpenAPIScope,
ReadOnlyWriteOnlyModelType,
ReuseScope,
Expand Down Expand Up @@ -323,6 +324,12 @@ def start_section(self, heading: str | None) -> None:
choices=[s.value for s in AllExportsCollisionStrategy],
default=None,
)
model_options.add_argument(
"--module-split-mode",
help="Split generated models into separate files. 'single': generate one file per model class.",
choices=[m.value for m in ModuleSplitMode],
default=None,
)

# ======================================================================================
# Typing options for generated models
Expand Down
1 change: 1 addition & 0 deletions src/datamodel_code_generator/cli_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class CLIOptionMeta:
"--all-exports-collision-strategy": CLIOptionMeta(
name="--all-exports-collision-strategy", category=OptionCategory.GENERAL
),
"--module-split-mode": CLIOptionMeta(name="--module-split-mode", category=OptionCategory.GENERAL),
"--disable-warnings": CLIOptionMeta(name="--disable-warnings", category=OptionCategory.GENERAL),
"--watch": CLIOptionMeta(name="--watch", category=OptionCategory.GENERAL),
"--watch-delay": CLIOptionMeta(name="--watch-delay", category=OptionCategory.GENERAL),
Expand Down
Loading
Loading