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, 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)

📝 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, GenerateConfig, GeneratedModules

# Your OpenAPI specification (string, 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:

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:

# 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. Parser classes also support the config parameter similar to generate().

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)

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
GraphQLParser GraphQLParserConfig

All config classes inherit from ParserConfig and include additional parser-specific options.

✨ 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