Generates Python data models from various schema formats including OpenAPI, JSON Schema, GraphQL, and raw data
—
Helper functions, utilities, and exception classes that support the core functionality of datamodel-code-generator. These provide YAML processing, version information, directory management, and structured error handling.
from datamodel_code_generator import (
get_version,
load_yaml,
load_yaml_from_path,
chdir,
infer_input_type,
is_openapi,
is_schema,
get_first_file,
enable_debug_message,
snooper_to_methods
)Functions for retrieving package version and compatibility information.
def get_version() -> str:
"""
Get the current package version string.
Returns:
Version string (e.g., "0.33.0")
Note:
Uses importlib.metadata.version() to retrieve version
from package metadata at runtime.
"""Functions for loading and parsing YAML content with safe loading practices.
def load_yaml(stream: str | TextIO) -> Any:
"""
Load YAML content from string or text stream.
Args:
stream: YAML content as string or TextIO stream
Returns:
Parsed YAML data structure (dict, list, scalar, etc.)
Raises:
yaml.parser.ParserError: If YAML content is malformed
Note:
Uses SafeLoader for security - prevents arbitrary code execution
"""
def load_yaml_from_path(path: Path, encoding: str) -> Any:
"""
Load YAML content from file path.
Args:
path: Path to YAML file
encoding: File encoding to use
Returns:
Parsed YAML data structure
Raises:
FileNotFoundError: If file does not exist
yaml.parser.ParserError: If YAML content is malformed
"""Context manager for temporary directory changes during generation.
@contextmanager
def chdir(path: Path | None) -> Iterator[None]:
"""
Context manager for temporary directory changes.
Changes working directory to specified path and restores
original directory on exit. If path is None, no change occurs.
Args:
path: Target directory path, or None for no change
Yields:
None
Example:
with chdir(Path("/tmp")):
# Working directory is now /tmp
generate(input_=Path("schema.json"), output=Path("models.py"))
# Working directory restored to original
"""Functions for automatically detecting input schema formats.
def infer_input_type(text: str) -> InputFileType:
"""
Automatically detect input file type from content.
Analyzes content structure to determine most likely schema format.
Uses heuristics like presence of 'openapi' field, '$schema' field,
and data structure patterns.
Args:
text: Raw input content as string
Returns:
Detected InputFileType enum value
Raises:
Error: If input type cannot be determined
Detection Logic:
1. Try parsing as YAML/JSON
2. Check for OpenAPI indicators ('openapi' field)
3. Check for JSON Schema indicators ('$schema', 'type', etc.)
4. Fall back to JSON for dict-like structures
5. Fall back to CSV if YAML parsing fails
"""
def is_openapi(data: dict) -> bool:
"""
Check if dictionary contains OpenAPI specification.
Args:
data: Parsed data dictionary
Returns:
True if data appears to be OpenAPI spec
Note:
Checks for presence of 'openapi' field in root level
"""
def is_schema(data: dict) -> bool:
"""
Check if dictionary contains JSON Schema.
Args:
data: Parsed data dictionary
Returns:
True if data appears to be JSON Schema
Detection Logic:
- Checks for $schema field with JSON Schema URL
- Checks for 'type' field with string value
- Checks for schema keywords (allOf, anyOf, oneOf)
- Checks for 'properties' field with dict value
"""Helper functions for file and directory operations.
def get_first_file(path: Path) -> Path:
"""
Get first file from path (file or directory).
If path is a file, returns the path itself.
If path is a directory, recursively finds first file.
Args:
path: File or directory path
Returns:
Path to first file found
Raises:
FileNotFoundError: If no files found in directory
"""Exception classes for structured error handling and user feedback.
class Error(Exception):
"""
Base exception class for datamodel-code-generator.
Provides structured error handling with descriptive messages
for generation failures, validation errors, and processing issues.
"""
def __init__(self, message: str) -> None:
"""
Initialize error with descriptive message.
Args:
message: Human-readable error description
"""
self.message: str = message
def __str__(self) -> str:
"""Return error message for display."""
return self.message
class InvalidClassNameError(Error):
"""
Raised when generated class names are invalid Python identifiers.
Occurs when schema titles or field names cannot be converted
to valid Python class names due to reserved keywords,
special characters, or naming conflicts.
"""
def __init__(self, class_name: str) -> None:
"""
Initialize with invalid class name.
Args:
class_name: The invalid class name that caused the error
"""
self.class_name = class_name
message = f"title={class_name!r} is invalid class name."
super().__init__(message=message)Functions for enabling debug tracing and diagnostics.
def enable_debug_message() -> None:
"""
Enable debug message tracing.
Activates pysnooper-based debug tracing for detailed
execution flow analysis. Requires 'debug' extra installation.
Raises:
Exception: If debug dependencies not installed
Note:
Install with: pip install 'datamodel-code-generator[debug]'
"""
def snooper_to_methods() -> Callable[..., Any]:
"""
Class decorator for adding debug tracing to all methods.
Returns:
Decorator function that adds snooper tracing to class methods
Usage:
@snooper_to_methods()
class MyParser:
def parse(self): ...
"""from datamodel_code_generator import get_version
print(f"Using datamodel-code-generator version: {get_version()}")
# Output: Using datamodel-code-generator version: 0.33.0from datamodel_code_generator import load_yaml, load_yaml_from_path
from pathlib import Path
# Load from string
yaml_content = """
openapi: 3.0.0
info:
title: My API
version: 1.0.0
"""
data = load_yaml(yaml_content)
print(data['info']['title']) # My API
# Load from file
schema_data = load_yaml_from_path(Path("schema.yaml"), encoding="utf-8")from datamodel_code_generator import chdir, generate
from pathlib import Path
# Generate with specific working directory
with chdir(Path("/project/schemas")):
generate(
input_=Path("api.yaml"), # Relative to /project/schemas
output=Path("../models/generated.py")
)from datamodel_code_generator import infer_input_type, is_openapi, is_schema
# Automatic detection
content = '{"openapi": "3.0.0", "info": {"title": "API"}}'
file_type = infer_input_type(content)
print(file_type) # InputFileType.OpenAPI
# Manual checking
import json
data = json.loads(content)
print(is_openapi(data)) # True
print(is_schema(data)) # Falsefrom datamodel_code_generator import generate, Error, InvalidClassNameError
try:
generate(
input_=Path("schema.json"),
output=Path("models.py")
)
except InvalidClassNameError as e:
print(f"Invalid class name: {e.class_name}")
# Handle class name normalization
except Error as e:
print(f"Generation error: {e.message}")
# Handle general generation errors
except FileNotFoundError:
print("Schema file not found")
# Handle file system errorsfrom datamodel_code_generator import enable_debug_message, snooper_to_methods
# Enable debug tracing (requires debug extra)
try:
enable_debug_message()
# Now generation will include detailed tracing
generate(input_=schema_path, output=output_path)
except Exception as e:
print(f"Debug mode requires: pip install 'datamodel-code-generator[debug]'")from datamodel_code_generator import Error
class CustomGenerationError(Error):
"""Custom error for application-specific handling."""
def __init__(self, context: str, original_error: Exception):
self.context = context
self.original_error = original_error
message = f"Generation failed in {context}: {original_error}"
super().__init__(message)
# Usage in application code
try:
generate(input_=schema_path, output=output_path)
except Error as e:
raise CustomGenerationError("schema processing", e)from datamodel_code_generator import is_openapi, is_schema, load_yaml
from pathlib import Path
def validate_schema_file(path: Path) -> str:
"""Validate and identify schema file type."""
try:
content = path.read_text()
data = load_yaml(content)
if is_openapi(data):
return "OpenAPI 3.x specification"
elif is_schema(data):
return "JSON Schema"
else:
return "Raw data (will be converted to JSON Schema)"
except Exception as e:
raise Error(f"Invalid schema file: {e}")
# Usage
try:
schema_type = validate_schema_file(Path("api.yaml"))
print(f"Detected: {schema_type}")
except Error as e:
print(f"Validation failed: {e.message}")Install with Tessl CLI
npx tessl i tessl/pypi-datamodel-code-generator