Skip to content

🐍 Using datamodel-code-generator as a 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.

📦 Installation

pip install 'datamodel-code-generator[http]'

📝 Getting Generated Code as String

When the output parameter is omitted (or set to None), generate() returns the generated code directly as a string:

from datamodel_code_generator import InputFileType, generate, DataModelType

json_schema: str = """{
    "type": "object",
    "properties": {
        "number": {"type": "number"},
        "street_name": {"type": "string"},
        "street_type": {"type": "string",
                        "enum": ["Street", "Avenue", "Boulevard"]
                        }
    }
}"""

result = generate(
    json_schema,
    input_file_type=InputFileType.JsonSchema,
    input_filename="example.json",
    output_model_type=DataModelType.PydanticV2BaseModel,
)
print(result)

📝 Multiple Module Output

When the schema generates multiple modules, generate() returns a GeneratedModules dictionary mapping module path tuples to generated code:

from datamodel_code_generator import InputFileType, generate, GeneratedModules

# Schema that generates multiple modules (e.g., with $ref to other files)
result: str | GeneratedModules = generate(
    openapi_spec,
    input_file_type=InputFileType.OpenAPI,
)

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:

from pathlib import Path
from tempfile import TemporaryDirectory
from datamodel_code_generator import InputFileType, generate
from datamodel_code_generator import 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')
    generate(
        json_schema,
        input_file_type=InputFileType.JsonSchema,
        input_filename="example.json",
        output=output,
        # set up the output model types
        output_model_type=DataModelType.PydanticV2BaseModel,
    )
    model: str = output.read_text()
print(model)

✨ Output:

# 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


🔧 Using the Parser Directly

You can also call the parser directly for more control:

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)

✨ Output:

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.


📖 See Also