🔧 Typing Customization¶
📋 Options¶
| Option | Description |
|---|---|
--allof-class-hierarchy |
Controls how allOf schemas are represented in the generated ... |
--allof-merge-mode |
Merge constraints from root model references in allOf schema... |
--disable-future-imports |
Prevent automatic addition of future imports in generate... |
--distribute-allof-over-unions |
Read an allOf with the anyOf and oneOf it holds or sit... |
--enum-field-as-literal |
Convert all enum fields to Literal types instead of Enum cla... |
--enum-field-as-literal-map |
Override enum/literal generation per-field via JSON mapping. |
--filter-literal-values |
Keep only the values of a const or an enum that meet the... |
--ignore-enum-constraints |
Ignore enum constraints and use base string type instead of ... |
--import-overrides |
Override modules for generated imports by symbol name. |
--intersect-allof-keywords |
Combine the keywords of every part of an allOf, a $ref w... |
--intersect-combined-schema-keywords |
Combine the keywords beside an anyOf or oneOf with each ... |
--keep-enum-member-values |
Give an enum class a value base only when it keeps every mem... |
--no-use-closed-typed-dict |
Disable PEP 728 TypedDict closed/extra_items generation. |
--no-use-specialized-enum |
Disable specialized Enum classes for Python 3.11+ code gener... |
--no-use-standard-collections |
Use typing.Dict/List instead of built-in dict/list for conta... |
--no-use-union-operator |
Use Union[X, Y] / Optional[X] instead of X |
--output-date-class |
Specify date class type for date schema fields. |
--output-datetime-class |
Specify datetime class type for date-time schema fields. |
--read-allof-parents-in-mro-order |
Read the allOf parents of every inherited schema in the orde... |
--read-const-beside-enum |
Read a const beside an enum as JSON Schema does. |
--read-unevaluated-properties |
Read a schema-valued unevaluatedProperties as `additionalP... |
--strict-types |
Enable strict type validation for specified Python types. |
--type-mappings |
Override default type mappings for schema formats. |
--type-overrides |
Replace schema model types with custom Python types via JSON... |
--type-overrides-replace-whole-type |
Make every --type-overrides value of a field replace the f... |
--use-annotated |
Use typing.Annotated for Field() with constraints. |
--use-bytes-for-content-media-type |
Type an OpenAPI string with a contentMediaType and no `con... |
--use-closed-typed-dict |
Generate TypedDict with PEP 728 closed/extra_items (default:... |
--use-decimal-for-multiple-of |
Generate Decimal types for fields with multipleOf constraint... |
--use-decimal-in-field-forms |
Write Decimal for a number with multipleOf in the field ... |
--use-encoded-str-for-constrained-base64 |
Check the constraints of a format: byte string on its base... |
--use-generic-container-types |
Use generic container types (Sequence, Mapping) for type hin... |
--use-non-positive-negative-number-constrained-types |
Use NonPositive/NonNegative types for number constraints. |
--use-object-type |
Use object instead of Any for unspecified object and array v... |
--use-pendulum |
Use pendulum types for date, time, and duration fields. |
--use-plain-alias-for-recursive-models |
Write the type alias of a model that names itself as a plain... |
--use-root-model-type-alias |
Generate RootModel as type alias format for better mypy supp... |
--use-single-dict-for-object-maps |
Type an object map as one dict instead of a union of dicts. |
--use-single-value-enum-as-const |
Treat enum with a single value as const with that value. |
--use-specialized-enum |
Generate StrEnum/IntEnum for string/integer enums (Python 3.... |
--use-standard-collections |
Use built-in dict/list instead of typing.Dict/List. |
--use-standard-primitive-types |
Use Python standard library types for string formats instead... |
--use-strict-str-for-base64 |
Make a format: byte string strict under `--strict-types st... |
--use-total-false-for-typed-dict |
Generate TypedDict declarations with total=False. |
--use-tuple-for-closed-arrays |
Generate tuple types for positional arrays that no other ite... |
--use-tuple-for-fixed-items |
Generate tuple types for arrays with items array syntax. |
--use-tuple-for-fixed-length-arrays |
Generate tuple types for homogeneous fixed-length arrays. |
--use-type-alias |
Use TypeAlias instead of root models for type definitions (e... |
--use-type-alias-type |
Use runtime TypeAliasType objects for aliases before Python ... |
--use-typed-map-values-beside-other-types |
Type the map values of type arrays that list object beside o... |
--use-typed-nullable-map-values |
Type the values of nullable maps as their schemas say instea... |
--use-union-operator |
Use |
--use-unique-items-as-set |
Generate set types for arrays with uniqueItems constraint. |
--use-unique-items-as-set-by-value |
Write a uniqueItems set only where its final items hash by v... |
--use-x-python-type-as-written |
Write a field's x-python-type as given: unions of every sp... |
🍳 Recipes¶
Use modern Python annotations¶
Target a recent Python version and prefer built-in collection and union syntax in generated types.
Options: --target-python-version, --use-union-operator, --use-standard-collections
Keep validation constraints in type hints¶
Combine Annotated hints with strict scalar handling when downstream tooling reads type metadata.
Options: --use-annotated, --field-constraints, --strict-types
--allof-class-hierarchy¶
Controls how allOf schemas are represented in the generated class hierarchy.
--allof-class-hierarchy if-no-conflict (default) creates parent classes for allOf schemas
only when there are no property conflicts between parent schemas. Otherwise, properties are merged into the child class
which is then decoupled from the parent classes and no longer inherits from them.
--allof-class-hierarchy always keeps class hierarchy for allOf schemas,
even in multiple inheritance scenarios where two parent schemas define the same property.
msgspec.Struct output declares the fields of parent classes whose layouts msgspec cannot combine instead of
inheriting from them.
Usage
-
--allof-class-hierarchy- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"StringDatatype": {
"description": "A base string type.",
"type": "string",
"pattern": "^\\S(.*\\S)?$"
},
"ConstrainedStringDatatype": {
"description": "A constrained string.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "type": "string", "minLength": 1, "pattern": "^[A-Z].*" }
]
},
"IntegerDatatype": {
"description": "A whole number.",
"type": "integer"
},
"NonNegativeIntegerDatatype": {
"description": "Non-negative integer.",
"allOf": [
{ "$ref": "#/definitions/IntegerDatatype" },
{ "minimum": 0 }
]
},
"BoundedIntegerDatatype": {
"description": "Integer between 0 and 100.",
"allOf": [
{ "$ref": "#/definitions/IntegerDatatype" },
{ "minimum": 0, "maximum": 100 }
]
},
"EmailDatatype": {
"description": "Email with format.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "format": "email" }
]
},
"FormattedStringDatatype": {
"description": "A string with email format.",
"type": "string",
"format": "email"
},
"ObjectBase": {
"type": "object",
"properties": {
"id": { "type": "integer" }
}
},
"ObjectWithAllOf": {
"description": "Object inheritance - not a root model.",
"allOf": [
{ "$ref": "#/definitions/ObjectBase" },
{ "type": "object", "properties": { "name": { "type": "string" } } }
]
},
"MultiRefAllOf": {
"description": "Multiple refs - not handled by new code.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "$ref": "#/definitions/IntegerDatatype" }
]
},
"NoConstraintAllOf": {
"description": "No constraints added.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" }
]
},
"IncompatibleTypeAllOf": {
"description": "Incompatible types.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "type": "boolean" }
]
},
"ConstraintWithProperties": {
"description": "Constraint item has properties.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "properties": { "extra": { "type": "string" } } }
]
},
"ConstraintWithItems": {
"description": "Constraint item has items.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "items": { "type": "string" } }
]
},
"NumberIntegerCompatible": {
"description": "Number and integer are compatible.",
"allOf": [
{ "$ref": "#/definitions/IntegerDatatype" },
{ "type": "number", "minimum": 0 }
]
},
"RefWithSchemaKeywords": {
"description": "Ref with additional schema keywords.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype", "minLength": 5 },
{ "maxLength": 100 }
]
},
"ArrayDatatype": {
"type": "array",
"items": { "type": "string" }
},
"RefToArrayAllOf": {
"description": "Ref to array - not a root model.",
"allOf": [
{ "$ref": "#/definitions/ArrayDatatype" },
{ "minItems": 1 }
]
},
"ObjectNoPropsDatatype": {
"type": "object"
},
"RefToObjectNoPropsAllOf": {
"description": "Ref to object without properties - not a root model.",
"allOf": [
{ "$ref": "#/definitions/ObjectNoPropsDatatype" },
{ "minProperties": 1 }
]
},
"PatternPropsDatatype": {
"patternProperties": {
"^S_": { "type": "string" }
}
},
"RefToPatternPropsAllOf": {
"description": "Ref to patternProperties - not a root model.",
"allOf": [
{ "$ref": "#/definitions/PatternPropsDatatype" },
{ "minProperties": 1 }
]
},
"NestedAllOfDatatype": {
"allOf": [
{ "type": "string" },
{ "minLength": 1 }
]
},
"RefToNestedAllOfAllOf": {
"description": "Ref to nested allOf root model.",
"allOf": [
{ "$ref": "#/definitions/NestedAllOfDatatype" },
{ "maxLength": 100 }
]
},
"ConstraintsOnlyDatatype": {
"description": "Constraints only, no type.",
"minLength": 1,
"pattern": "^[A-Z]"
},
"RefToConstraintsOnlyAllOf": {
"description": "Ref to constraints-only schema.",
"allOf": [
{ "$ref": "#/definitions/ConstraintsOnlyDatatype" },
{ "maxLength": 100 }
]
},
"NoDescriptionAllOf": {
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "minLength": 5 }
]
},
"EmptyConstraintItemAllOf": {
"description": "AllOf with empty constraint item.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{},
{ "maxLength": 50 }
]
},
"ConflictingFormatAllOf": {
"description": "Conflicting formats - falls back to existing behavior.",
"allOf": [
{ "$ref": "#/definitions/FormattedStringDatatype" },
{ "format": "date-time" }
]
}
},
"type": "object",
"properties": {
"name": { "$ref": "#/definitions/ConstrainedStringDatatype" },
"count": { "$ref": "#/definitions/NonNegativeIntegerDatatype" },
"percentage": { "$ref": "#/definitions/BoundedIntegerDatatype" },
"email": { "$ref": "#/definitions/EmailDatatype" },
"obj": { "$ref": "#/definitions/ObjectWithAllOf" },
"multi": { "$ref": "#/definitions/MultiRefAllOf" },
"noconstraint": { "$ref": "#/definitions/NoConstraintAllOf" },
"incompatible": { "$ref": "#/definitions/IncompatibleTypeAllOf" },
"withprops": { "$ref": "#/definitions/ConstraintWithProperties" },
"withitems": { "$ref": "#/definitions/ConstraintWithItems" },
"numint": { "$ref": "#/definitions/NumberIntegerCompatible" },
"refwithkw": { "$ref": "#/definitions/RefWithSchemaKeywords" },
"refarr": { "$ref": "#/definitions/RefToArrayAllOf" },
"refobjnoprops": { "$ref": "#/definitions/RefToObjectNoPropsAllOf" },
"refpatternprops": { "$ref": "#/definitions/RefToPatternPropsAllOf" },
"refnestedallof": { "$ref": "#/definitions/RefToNestedAllOfAllOf" },
"refconstraintsonly": { "$ref": "#/definitions/RefToConstraintsOnlyAllOf" },
"nodescription": { "$ref": "#/definitions/NoDescriptionAllOf" },
"emptyconstraint": { "$ref": "#/definitions/EmptyConstraintItemAllOf" },
"conflictingformat": { "$ref": "#/definitions/ConflictingFormatAllOf" }
}
}
Output:
# generated by datamodel-codegen:
# filename: allof_class_hierarchy.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field, constr
class Entity(BaseModel):
type: str
type_list: list[str] | None = ['playground:Entity']
class Entity2(BaseModel):
type: str
type_list: list[str]
class Thing(Entity):
type: str
type_list: list[str] | None = ['playground:Thing']
name: constr(min_length=1) = Field(..., description='The things name')
class Location(Entity2):
type: str
type_list: list[str]
address: constr(min_length=5) = Field(
..., description='The address of the location'
)
class Person(Thing, Location):
name: constr(min_length=1) = Field(..., description="The person's name")
type: str
type_list: list[str]
# generated by datamodel-codegen:
# filename: allof_class_hierarchy.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field, constr
class Person(BaseModel):
name: constr(min_length=1) = Field(..., description='The things name')
type: Any | None = 'playground:Location'
type_list: list[Any] | None = [
'playground:Person',
'playground:Thing',
'playground:Location',
]
address: constr(min_length=5) = Field(
..., description='The address of the location'
)
class Entity(BaseModel):
type: str
type_list: list[str] | None = ['playground:Entity']
class Entity2(BaseModel):
type: str
type_list: list[str]
class Thing(Entity):
type: str
type_list: list[str] | None = ['playground:Thing']
name: constr(min_length=1) = Field(..., description='The things name')
class Location(Entity2):
type: str
type_list: list[str]
address: constr(min_length=5) = Field(
..., description='The address of the location'
)
--allof-merge-mode¶
Merge constraints from root model references in allOf schemas.
The --allof-merge-mode constraints merges only constraint properties
(minLength, maximum, etc.) from parent schemas referenced in allOf.
This ensures child schemas inherit validation constraints while keeping
other properties separate.
Usage
-
--allof-merge-mode- the option documented here
Examples
Input Schema:
openapi: "3.0.0"
info:
title: Test materialize allOf defaults
version: "1.0.0"
components:
schemas:
Parent:
type: object
properties:
name:
type: string
default: "parent_default"
minLength: 1
count:
type: integer
default: 10
minimum: 0
Child:
allOf:
- $ref: "#/components/schemas/Parent"
- type: object
properties:
name:
maxLength: 100
count:
maximum: 1000
Output:
# generated by datamodel-codegen:
# filename: allof_materialize_defaults.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, conint, constr
class Parent(BaseModel):
name: constr(min_length=1) | None = 'parent_default'
count: conint(ge=0) | None = 10
class Child(Parent):
name: constr(min_length=1, max_length=100) | None = 'parent_default'
count: conint(ge=0, le=1000) | None = 10
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"StringDatatype": {
"description": "A base string type.",
"type": "string",
"pattern": "^\\S(.*\\S)?$"
},
"ConstrainedStringDatatype": {
"description": "A constrained string.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "type": "string", "minLength": 1, "pattern": "^[A-Z].*" }
]
},
"IntegerDatatype": {
"description": "A whole number.",
"type": "integer"
},
"NonNegativeIntegerDatatype": {
"description": "Non-negative integer.",
"allOf": [
{ "$ref": "#/definitions/IntegerDatatype" },
{ "minimum": 0 }
]
},
"BoundedIntegerDatatype": {
"description": "Integer between 0 and 100.",
"allOf": [
{ "$ref": "#/definitions/IntegerDatatype" },
{ "minimum": 0, "maximum": 100 }
]
},
"EmailDatatype": {
"description": "Email with format.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "format": "email" }
]
},
"FormattedStringDatatype": {
"description": "A string with email format.",
"type": "string",
"format": "email"
},
"ObjectBase": {
"type": "object",
"properties": {
"id": { "type": "integer" }
}
},
"ObjectWithAllOf": {
"description": "Object inheritance - not a root model.",
"allOf": [
{ "$ref": "#/definitions/ObjectBase" },
{ "type": "object", "properties": { "name": { "type": "string" } } }
]
},
"MultiRefAllOf": {
"description": "Multiple refs - not handled by new code.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "$ref": "#/definitions/IntegerDatatype" }
]
},
"NoConstraintAllOf": {
"description": "No constraints added.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" }
]
},
"IncompatibleTypeAllOf": {
"description": "Incompatible types.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "type": "boolean" }
]
},
"ConstraintWithProperties": {
"description": "Constraint item has properties.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "properties": { "extra": { "type": "string" } } }
]
},
"ConstraintWithItems": {
"description": "Constraint item has items.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "items": { "type": "string" } }
]
},
"NumberIntegerCompatible": {
"description": "Number and integer are compatible.",
"allOf": [
{ "$ref": "#/definitions/IntegerDatatype" },
{ "type": "number", "minimum": 0 }
]
},
"RefWithSchemaKeywords": {
"description": "Ref with additional schema keywords.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype", "minLength": 5 },
{ "maxLength": 100 }
]
},
"ArrayDatatype": {
"type": "array",
"items": { "type": "string" }
},
"RefToArrayAllOf": {
"description": "Ref to array - not a root model.",
"allOf": [
{ "$ref": "#/definitions/ArrayDatatype" },
{ "minItems": 1 }
]
},
"ObjectNoPropsDatatype": {
"type": "object"
},
"RefToObjectNoPropsAllOf": {
"description": "Ref to object without properties - not a root model.",
"allOf": [
{ "$ref": "#/definitions/ObjectNoPropsDatatype" },
{ "minProperties": 1 }
]
},
"PatternPropsDatatype": {
"patternProperties": {
"^S_": { "type": "string" }
}
},
"RefToPatternPropsAllOf": {
"description": "Ref to patternProperties - not a root model.",
"allOf": [
{ "$ref": "#/definitions/PatternPropsDatatype" },
{ "minProperties": 1 }
]
},
"NestedAllOfDatatype": {
"allOf": [
{ "type": "string" },
{ "minLength": 1 }
]
},
"RefToNestedAllOfAllOf": {
"description": "Ref to nested allOf root model.",
"allOf": [
{ "$ref": "#/definitions/NestedAllOfDatatype" },
{ "maxLength": 100 }
]
},
"ConstraintsOnlyDatatype": {
"description": "Constraints only, no type.",
"minLength": 1,
"pattern": "^[A-Z]"
},
"RefToConstraintsOnlyAllOf": {
"description": "Ref to constraints-only schema.",
"allOf": [
{ "$ref": "#/definitions/ConstraintsOnlyDatatype" },
{ "maxLength": 100 }
]
},
"NoDescriptionAllOf": {
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{ "minLength": 5 }
]
},
"EmptyConstraintItemAllOf": {
"description": "AllOf with empty constraint item.",
"allOf": [
{ "$ref": "#/definitions/StringDatatype" },
{},
{ "maxLength": 50 }
]
},
"ConflictingFormatAllOf": {
"description": "Conflicting formats - falls back to existing behavior.",
"allOf": [
{ "$ref": "#/definitions/FormattedStringDatatype" },
{ "format": "date-time" }
]
}
},
"type": "object",
"properties": {
"name": { "$ref": "#/definitions/ConstrainedStringDatatype" },
"count": { "$ref": "#/definitions/NonNegativeIntegerDatatype" },
"percentage": { "$ref": "#/definitions/BoundedIntegerDatatype" },
"email": { "$ref": "#/definitions/EmailDatatype" },
"obj": { "$ref": "#/definitions/ObjectWithAllOf" },
"multi": { "$ref": "#/definitions/MultiRefAllOf" },
"noconstraint": { "$ref": "#/definitions/NoConstraintAllOf" },
"incompatible": { "$ref": "#/definitions/IncompatibleTypeAllOf" },
"withprops": { "$ref": "#/definitions/ConstraintWithProperties" },
"withitems": { "$ref": "#/definitions/ConstraintWithItems" },
"numint": { "$ref": "#/definitions/NumberIntegerCompatible" },
"refwithkw": { "$ref": "#/definitions/RefWithSchemaKeywords" },
"refarr": { "$ref": "#/definitions/RefToArrayAllOf" },
"refobjnoprops": { "$ref": "#/definitions/RefToObjectNoPropsAllOf" },
"refpatternprops": { "$ref": "#/definitions/RefToPatternPropsAllOf" },
"refnestedallof": { "$ref": "#/definitions/RefToNestedAllOfAllOf" },
"refconstraintsonly": { "$ref": "#/definitions/RefToConstraintsOnlyAllOf" },
"nodescription": { "$ref": "#/definitions/NoDescriptionAllOf" },
"emptyconstraint": { "$ref": "#/definitions/EmptyConstraintItemAllOf" },
"conflictingformat": { "$ref": "#/definitions/ConflictingFormatAllOf" }
}
}
Output:
# generated by datamodel-codegen:
# filename: allof_root_model_constraints.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, ConfigDict, EmailStr, Field, RootModel, conint, constr
class StringDatatype(RootModel[constr(pattern=r'^\S(.*\S)?$')]):
root: constr(pattern=r'^\S(.*\S)?$') = Field(..., description='A base string type.')
class ConstrainedStringDatatype(RootModel[str]):
model_config = ConfigDict(
regex_engine="python-re",
)
root: constr(pattern=r'(?=^\S(.*\S)?$)(?=^[A-Z].*)', min_length=1) = Field(
..., description='A constrained string.'
)
class IntegerDatatype(RootModel[int]):
root: int = Field(..., description='A whole number.')
class NonNegativeIntegerDatatype(RootModel[conint(ge=0)]):
root: conint(ge=0) = Field(..., description='Non-negative integer.')
class BoundedIntegerDatatype(RootModel[conint(ge=0, le=100)]):
root: conint(ge=0, le=100) = Field(..., description='Integer between 0 and 100.')
class EmailDatatype(RootModel[EmailStr]):
root: EmailStr = Field(..., description='Email with format.')
class FormattedStringDatatype(RootModel[EmailStr]):
root: EmailStr = Field(..., description='A string with email format.')
class ObjectBase(BaseModel):
id: int | None = None
class ObjectWithAllOf(ObjectBase):
name: str | None = None
class MultiRefAllOf(BaseModel):
pass
class NoConstraintAllOf(RootModel[StringDatatype]):
root: StringDatatype = Field(..., description='No constraints added.')
class IncompatibleTypeAllOf(BaseModel):
pass
class ConstraintWithProperties(BaseModel):
extra: str | None = None
class ConstraintWithItems(RootModel[StringDatatype]):
root: StringDatatype = Field(..., description='Constraint item has items.')
class NumberIntegerCompatible(RootModel[conint(ge=0)]):
root: conint(ge=0) = Field(..., description='Number and integer are compatible.')
class RefWithSchemaKeywords(
RootModel[constr(pattern=r'^\S(.*\S)?$', min_length=5, max_length=100)]
):
root: constr(pattern=r'^\S(.*\S)?$', min_length=5, max_length=100) = Field(
..., description='Ref with additional schema keywords.'
)
class ArrayDatatype(RootModel[list[str]]):
root: list[str]
class RefToArrayAllOf(RootModel[list[str]]):
root: list[str] = Field(
..., description='Ref to array - not a root model.', min_length=1
)
class ObjectNoPropsDatatype(BaseModel):
pass
class RefToObjectNoPropsAllOf(ObjectNoPropsDatatype):
pass
class PatternPropsDatatype(RootModel[dict[constr(pattern=r'^S_'), str]]):
root: dict[constr(pattern=r'^S_'), str]
class RefToPatternPropsAllOf(BaseModel):
pass
class NestedAllOfDatatype(RootModel[constr(min_length=1)]):
root: constr(min_length=1)
class RefToNestedAllOfAllOf(RootModel[constr(min_length=1, max_length=100)]):
root: constr(min_length=1, max_length=100) = Field(
..., description='Ref to nested allOf root model.'
)
class ConstraintsOnlyDatatype(RootModel[Any]):
root: Any = Field(..., description='Constraints only, no type.')
class RefToConstraintsOnlyAllOf(RootModel[Any]):
root: Any = Field(..., description='Ref to constraints-only schema.')
class NoDescriptionAllOf(RootModel[constr(pattern=r'^\S(.*\S)?$', min_length=5)]):
root: constr(pattern=r'^\S(.*\S)?$', min_length=5) = Field(
..., description='A base string type.'
)
class EmptyConstraintItemAllOf(
RootModel[constr(pattern=r'^\S(.*\S)?$', max_length=50)]
):
root: constr(pattern=r'^\S(.*\S)?$', max_length=50) = Field(
..., description='AllOf with empty constraint item.'
)
class ConflictingFormatAllOf(BaseModel):
pass
class Model(BaseModel):
name: ConstrainedStringDatatype | None = None
count: NonNegativeIntegerDatatype | None = None
percentage: BoundedIntegerDatatype | None = None
email: EmailDatatype | None = None
obj: ObjectWithAllOf | None = None
multi: MultiRefAllOf | None = None
noconstraint: NoConstraintAllOf | None = None
incompatible: IncompatibleTypeAllOf | None = None
withprops: ConstraintWithProperties | None = None
withitems: ConstraintWithItems | None = None
numint: NumberIntegerCompatible | None = None
refwithkw: RefWithSchemaKeywords | None = None
refarr: RefToArrayAllOf | None = None
refobjnoprops: RefToObjectNoPropsAllOf | None = None
refpatternprops: RefToPatternPropsAllOf | None = None
refnestedallof: RefToNestedAllOfAllOf | None = None
refconstraintsonly: RefToConstraintsOnlyAllOf | None = None
nodescription: NoDescriptionAllOf | None = None
emptyconstraint: EmptyConstraintItemAllOf | None = None
conflictingformat: ConflictingFormatAllOf | None = None
# generated by datamodel-codegen:
# filename: allof_root_model_constraints.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, EmailStr, Field, RootModel, conint, constr
class StringDatatype(RootModel[constr(pattern=r'^\S(.*\S)?$')]):
root: constr(pattern=r'^\S(.*\S)?$') = Field(..., description='A base string type.')
class ConstrainedStringDatatype(RootModel[constr(pattern=r'^[A-Z].*', min_length=1)]):
root: constr(pattern=r'^[A-Z].*', min_length=1) = Field(
..., description='A constrained string.'
)
class IntegerDatatype(RootModel[int]):
root: int = Field(..., description='A whole number.')
class NonNegativeIntegerDatatype(RootModel[conint(ge=0)]):
root: conint(ge=0) = Field(..., description='Non-negative integer.')
class BoundedIntegerDatatype(RootModel[conint(ge=0, le=100)]):
root: conint(ge=0, le=100) = Field(..., description='Integer between 0 and 100.')
class EmailDatatype(RootModel[EmailStr]):
root: EmailStr = Field(..., description='Email with format.')
class FormattedStringDatatype(RootModel[EmailStr]):
root: EmailStr = Field(..., description='A string with email format.')
class ObjectBase(BaseModel):
id: int | None = None
class ObjectWithAllOf(ObjectBase):
name: str | None = None
class MultiRefAllOf(BaseModel):
pass
class NoConstraintAllOf(RootModel[StringDatatype]):
root: StringDatatype = Field(..., description='No constraints added.')
class IncompatibleTypeAllOf(BaseModel):
pass
class ConstraintWithProperties(BaseModel):
extra: str | None = None
class ConstraintWithItems(RootModel[StringDatatype]):
root: StringDatatype = Field(..., description='Constraint item has items.')
class NumberIntegerCompatible(RootModel[conint(ge=0)]):
root: conint(ge=0) = Field(..., description='Number and integer are compatible.')
class RefWithSchemaKeywords(
RootModel[constr(pattern=r'^\S(.*\S)?$', min_length=5, max_length=100)]
):
root: constr(pattern=r'^\S(.*\S)?$', min_length=5, max_length=100) = Field(
..., description='Ref with additional schema keywords.'
)
class ArrayDatatype(RootModel[list[str]]):
root: list[str]
class RefToArrayAllOf(RootModel[list[str]]):
root: list[str] = Field(
..., description='Ref to array - not a root model.', min_length=1
)
class ObjectNoPropsDatatype(BaseModel):
pass
class RefToObjectNoPropsAllOf(ObjectNoPropsDatatype):
pass
class PatternPropsDatatype(RootModel[dict[constr(pattern=r'^S_'), str]]):
root: dict[constr(pattern=r'^S_'), str]
class RefToPatternPropsAllOf(BaseModel):
pass
class NestedAllOfDatatype(RootModel[constr(min_length=1)]):
root: constr(min_length=1)
class RefToNestedAllOfAllOf(RootModel[constr(min_length=1, max_length=100)]):
root: constr(min_length=1, max_length=100) = Field(
..., description='Ref to nested allOf root model.'
)
class ConstraintsOnlyDatatype(RootModel[Any]):
root: Any = Field(..., description='Constraints only, no type.')
class RefToConstraintsOnlyAllOf(RootModel[Any]):
root: Any = Field(..., description='Ref to constraints-only schema.')
class NoDescriptionAllOf(RootModel[constr(pattern=r'^\S(.*\S)?$', min_length=5)]):
root: constr(pattern=r'^\S(.*\S)?$', min_length=5) = Field(
..., description='A base string type.'
)
class EmptyConstraintItemAllOf(
RootModel[constr(pattern=r'^\S(.*\S)?$', max_length=50)]
):
root: constr(pattern=r'^\S(.*\S)?$', max_length=50) = Field(
..., description='AllOf with empty constraint item.'
)
class ConflictingFormatAllOf(BaseModel):
pass
class Model(BaseModel):
name: ConstrainedStringDatatype | None = None
count: NonNegativeIntegerDatatype | None = None
percentage: BoundedIntegerDatatype | None = None
email: EmailDatatype | None = None
obj: ObjectWithAllOf | None = None
multi: MultiRefAllOf | None = None
noconstraint: NoConstraintAllOf | None = None
incompatible: IncompatibleTypeAllOf | None = None
withprops: ConstraintWithProperties | None = None
withitems: ConstraintWithItems | None = None
numint: NumberIntegerCompatible | None = None
refwithkw: RefWithSchemaKeywords | None = None
refarr: RefToArrayAllOf | None = None
refobjnoprops: RefToObjectNoPropsAllOf | None = None
refpatternprops: RefToPatternPropsAllOf | None = None
refnestedallof: RefToNestedAllOfAllOf | None = None
refconstraintsonly: RefToConstraintsOnlyAllOf | None = None
nodescription: NoDescriptionAllOf | None = None
emptyconstraint: EmptyConstraintItemAllOf | None = None
conflictingformat: ConflictingFormatAllOf | None = None
--disable-future-imports¶
Prevent automatic addition of future imports in generated code.
The --disable-future-imports option stops the generator from adding 'from future import annotations' to the output. This is useful when you need compatibility with tools or environments that don't support postponed evaluation of annotations (PEP 563).
See also: Python Version Compatibility
Usage
datamodel-codegen --input keep_model_order_field_references.json --disable-future-imports --target-python-version 3.10 # (1)!
-
--disable-future-imports- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "DescriptionType",
"type": "object",
"properties": {
"metadata": {
"type": "array",
"items": {
"$ref": "#/definitions/Metadata"
}
}
},
"definitions": {
"Metadata": {
"title": "Metadata",
"type": "object",
"properties": {
"title": {
"type": "string"
}
}
}
}
}
Output:
--distribute-allof-over-unions¶
Read an allOf with the anyOf and oneOf it holds or sits beside, as JSON Schema does.
A schema with an allOf beside an anyOf or oneOf admits a value that every allOf member and one branch admit.
An inline branch is parsed with the allOf merged in, but a $ref branch takes only the properties and required
beside it, so {allOf: [Base], oneOf: [Cat, Dog]} writes Cat | Dog and drops Base. With
--distribute-allof-over-unions such a branch gets a class whose bases are the branch and the allOf members
(Pet1(Cat, Base)), at a definition, a property, an array item and a map value alike, and an OpenAPI request or
response body is that union too (without the option it is parsed by its allOf and the union is dropped). A $ref
branch that names no object takes the value keywords beside the union, as an inline branch does, so minimum: 5
beside anyOf: [{$ref: Quantity}, {type: string}] rejects 3. An allOf member's value keywords meet such a branch
under --use-site-models-for-constrained-refs, as they meet a $ref member of an allOf there.
An allOf whose members hold several anyOf or oneOf admits a value that meets one branch of each. Without the
option their branches join one union, each with the other parts (and the inline branches of a later anyOf replace
those of an earlier one); with it the allOf is one union variant per combination of one branch of each
(M6(M1, M3, M5), a class each branch appears in once), at most 128 per allOf (above that the branches join one
union, with a warning). A $ref member that names an allOf over a union, which was a base that later passes drop, is
read in its place, so its union joins those of the site (Leaf4(Leaf1, Leaf3)). The value branches of these unions are
read at a field (RootModel[constr(min_length=2) | int] where 0.89.0 writes Any), beside a $ref member that is
the type of a field or an item, and beside object branches (R3m3 | constr(min_length=2)), as an allOf of value
unions that would be a model without fields is read without the option.
Usage
-
--distribute-allof-over-unions- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Model",
"type": "object",
"properties": {
"pet": {
"$ref": "#/$defs/Pet"
},
"pet_inline_member": {
"$ref": "#/$defs/PetInlineMember"
},
"pet_mixed": {
"$ref": "#/$defs/PetMixed"
},
"pet_inline": {
"$ref": "#/$defs/PetInline"
},
"pet_props": {
"$ref": "#/$defs/PetProps"
},
"pet_field": {
"allOf": [
{
"$ref": "#/$defs/Base"
}
],
"oneOf": [
{
"$ref": "#/$defs/Cat"
},
{
"$ref": "#/$defs/Dog"
}
]
},
"items": {
"type": "array",
"items": {
"allOf": [
{
"$ref": "#/$defs/Base"
}
],
"anyOf": [
{
"$ref": "#/$defs/Cat"
},
{
"$ref": "#/$defs/Dog"
}
]
}
},
"values": {
"type": "object",
"additionalProperties": {
"allOf": [
{
"$ref": "#/$defs/Base"
}
],
"anyOf": [
{
"$ref": "#/$defs/Cat"
},
{
"$ref": "#/$defs/Dog"
}
]
}
}
},
"$defs": {
"Base": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
}
},
"Cat": {
"type": "object",
"required": [
"meow"
],
"properties": {
"meow": {
"type": "boolean"
}
}
},
"Dog": {
"type": "object",
"required": [
"bark"
],
"properties": {
"bark": {
"type": "boolean"
}
}
},
"Pet": {
"allOf": [
{
"$ref": "#/$defs/Base"
}
],
"oneOf": [
{
"$ref": "#/$defs/Cat"
},
{
"$ref": "#/$defs/Dog"
}
]
},
"PetInlineMember": {
"allOf": [
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
}
}
],
"anyOf": [
{
"$ref": "#/$defs/Cat"
},
{
"$ref": "#/$defs/Dog"
}
]
},
"PetMixed": {
"allOf": [
{
"$ref": "#/$defs/Base"
}
],
"anyOf": [
{
"$ref": "#/$defs/Cat"
},
{
"type": "object",
"required": [
"bark"
],
"properties": {
"bark": {
"type": "boolean"
}
}
}
]
},
"PetInline": {
"allOf": [
{
"$ref": "#/$defs/Base"
}
],
"oneOf": [
{
"type": "object",
"required": [
"meow"
],
"properties": {
"meow": {
"type": "boolean"
}
}
},
{
"type": "object",
"required": [
"bark"
],
"properties": {
"bark": {
"type": "boolean"
}
}
}
]
},
"PetProps": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
},
"oneOf": [
{
"$ref": "#/$defs/Cat"
},
{
"$ref": "#/$defs/Dog"
}
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: allof_beside_union.json
from __future__ import annotations
from pydantic import BaseModel, RootModel
class Base(BaseModel):
id: str
class Cat(BaseModel):
meow: bool
class Dog(BaseModel):
bark: bool
class Pet1(Cat, Base):
pass
class Pet2(Dog, Base):
pass
class Pet(RootModel[Pet1 | Pet2]):
root: Pet1 | Pet2
class PetInlineMember1(Cat):
id: str
class PetInlineMember2(Dog):
id: str
class PetInlineMember(RootModel[PetInlineMember1 | PetInlineMember2]):
root: PetInlineMember1 | PetInlineMember2
class PetMixed1(Base):
bark: bool
class PetMixed2(Cat, Base):
pass
class PetMixed(RootModel[PetMixed2 | PetMixed1]):
root: PetMixed2 | PetMixed1
class PetInline1(Base):
meow: bool
class PetInline2(Base):
bark: bool
class PetInline(RootModel[PetInline1 | PetInline2]):
root: PetInline1 | PetInline2
class PetProps1(Cat):
id: str
class PetProps2(Dog):
id: str
class PetProps(RootModel[PetProps1 | PetProps2]):
root: PetProps1 | PetProps2
class PetField(Cat, Base):
pass
class PetField1(Dog, Base):
pass
class Items(Cat, Base):
pass
class Items1(Dog, Base):
pass
class Values(Cat, Base):
pass
class Values1(Dog, Base):
pass
class Model(BaseModel):
pet: Pet | None = None
pet_inline_member: PetInlineMember | None = None
pet_mixed: PetMixed | None = None
pet_inline: PetInline | None = None
pet_props: PetProps | None = None
pet_field: PetField | PetField1 | None = None
items: list[Items | Items1] | None = None
values: dict[str, Values | Values1] | None = None
# generated by datamodel-codegen:
# filename: allof_beside_union.json
from __future__ import annotations
from pydantic import BaseModel, RootModel
class Base(BaseModel):
id: str
class Cat(BaseModel):
meow: bool
class Dog(BaseModel):
bark: bool
class Pet(RootModel[Cat | Dog]):
root: Cat | Dog
class PetInlineMember(RootModel[Cat | Dog]):
root: Cat | Dog
class PetMixed1(Base):
bark: bool
class PetMixed(RootModel[Cat | PetMixed1]):
root: Cat | PetMixed1
class PetInline1(Base):
meow: bool
class PetInline2(Base):
bark: bool
class PetInline(RootModel[PetInline1 | PetInline2]):
root: PetInline1 | PetInline2
class PetProps1(Cat):
id: str
class PetProps2(Dog):
id: str
class PetProps(RootModel[PetProps1 | PetProps2]):
root: PetProps1 | PetProps2
class Model(BaseModel):
pet: Pet | None = None
pet_inline_member: PetInlineMember | None = None
pet_mixed: PetMixed | None = None
pet_inline: PetInline | None = None
pet_props: PetProps | None = None
pet_field: Cat | Dog | None = None
items: list[Cat | Dog] | None = None
values: dict[str, Cat | Dog] | None = None
--enum-field-as-literal¶
Convert all enum fields to Literal types instead of Enum classes.
The --enum-field-as-literal all flag converts all enum types to Literal
type annotations. This is useful when you want string literal types instead
of Enum classes for all enumerations.
Usage
-
--enum-field-as-literal- the option documented here
Examples
Input Schema:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
components:
schemas:
Pet:
required:
- id
- name
- number
- boolean
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
kind:
type: string
enum: ['dog', 'cat']
type:
type: string
enum: [ 'animal' ]
number:
type: integer
enum: [ 1 ]
boolean:
type: boolean
enum: [ true ]
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
animal:
type: object
properties:
kind:
type: string
enum: ['snake', 'rabbit']
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
EnumObject:
type: object
properties:
type:
enum: ['a', 'b']
type: string
EnumRoot:
enum: ['a', 'b']
type: string
IntEnum:
enum: [1,2]
type: number
AliasEnum:
enum: [1,2,3]
type: number
x-enum-varnames: ['a', 'b', 'c']
MultipleTypeEnum:
enum: [ "red", "amber", "green", null, 42 ]
singleEnum:
enum: [ "pet" ]
type: string
arrayEnum:
type: array
items: [
{ enum: [ "cat" ] },
{ enum: [ "dog"]}
]
nestedNullableEnum:
type: object
properties:
nested_version:
type: string
nullable: true
default: RC1
description: nullable enum
example: RC2
enum:
- RC1
- RC1N
- RC2
- RC2N
- RC3
- RC4
- null
version:
type: string
nullable: true
default: RC1
description: nullable enum
example: RC2
enum:
- RC1
- RC1N
- RC2
- RC2N
- RC3
- RC4
- null
Output:
# generated by datamodel-codegen:
# filename: enum_models.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from typing import Literal
from pydantic import BaseModel, Field, RootModel
class Kind(Enum):
dog = 'dog'
cat = 'cat'
class Pet(BaseModel):
id: int
name: str
tag: str | None = None
kind: Kind | None = None
type: Literal['animal'] | None = None
number: Literal[1]
boolean: Literal[True]
class Pets(RootModel[list[Pet]]):
root: list[Pet]
class Kind1(Enum):
snake = 'snake'
rabbit = 'rabbit'
class Animal(BaseModel):
kind: Kind1 | None = None
class Error(BaseModel):
code: int
message: str
class Type(Enum):
a = 'a'
b = 'b'
class EnumObject(BaseModel):
type: Type | None = None
class EnumRoot(Enum):
a = 'a'
b = 'b'
class IntEnum(Enum):
number_1 = 1
number_2 = 2
class AliasEnum(Enum):
a = 1
b = 2
c = 3
class MultipleTypeEnum(Enum):
red = 'red'
amber = 'amber'
green = 'green'
NoneType_None = None
int_42 = 42
class SingleEnum(RootModel[Literal['pet']]):
root: Literal['pet']
class ArrayEnum(RootModel[list[Literal['cat'] | Literal['dog']]]):
root: list[Literal['cat'] | Literal['dog']]
class NestedVersionEnum(Enum):
RC1 = 'RC1'
RC1N = 'RC1N'
RC2 = 'RC2'
RC2N = 'RC2N'
RC3 = 'RC3'
RC4 = 'RC4'
class NestedVersion(RootModel[NestedVersionEnum | None]):
root: NestedVersionEnum | None = Field(
'RC1', description='nullable enum', examples=['RC2']
)
class NestedNullableEnum(BaseModel):
nested_version: NestedVersion | None = Field(
'RC1', description='nullable enum', examples=['RC2'], validate_default=True
)
class VersionEnum(Enum):
RC1 = 'RC1'
RC1N = 'RC1N'
RC2 = 'RC2'
RC2N = 'RC2N'
RC3 = 'RC3'
RC4 = 'RC4'
class Version(RootModel[VersionEnum | None]):
root: VersionEnum | None = Field(
'RC1', description='nullable enum', examples=['RC2']
)
Input Schema:
$schema: http://json-schema.org/draft-07/schema#
type: object
title: Config
properties:
mode:
title: Mode
type: string
oneOf:
- title: fast
const: fast
- title: slow
const: slow
modes:
type: array
items:
type: string
oneOf:
- const: a
- const: b
Output:
# generated by datamodel-codegen:
# filename: oneof_const_enum_nested.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field
class Config(BaseModel):
mode: Literal['fast', 'slow'] | None = Field(None, title='Mode')
modes: list[Literal['a', 'b']] | None = None
Input Schema:
"Employee shift status"
enum EmployeeShiftStatus {
"not on shift"
NOT_ON_SHIFT
"on shift"
ON_SHIFT
}
enum Color {
RED
GREEN
BLUE
}
enum EnumWithOneField {
FIELD
}
Output:
# generated by datamodel-codegen:
# filename: enums.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Literal
from pydantic import RootModel
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
String = TypeAliasType("String", str)
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class Color(RootModel[Literal['BLUE', 'GREEN', 'RED']]):
root: Literal['BLUE', 'GREEN', 'RED']
class EmployeeShiftStatus(RootModel[Literal['NOT_ON_SHIFT', 'ON_SHIFT']]):
"""
Employee shift status
"""
root: Literal['NOT_ON_SHIFT', 'ON_SHIFT']
class EnumWithOneField(RootModel[Literal['FIELD']]):
root: Literal['FIELD']
# generated by datamodel-codegen:
# filename: enums.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
String = TypeAliasType("String", str)
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class Color(Enum):
BLUE = 'BLUE'
GREEN = 'GREEN'
RED = 'RED'
class EmployeeShiftStatus(Enum):
"""
Employee shift status
"""
NOT_ON_SHIFT = 'NOT_ON_SHIFT'
ON_SHIFT = 'ON_SHIFT'
class EnumWithOneField(Enum):
FIELD = 'FIELD'
--enum-field-as-literal-map¶
Override enum/literal generation per-field via JSON mapping.
The --enum-field-as-literal-map option allows per-field control over whether
to generate Literal types or Enum classes. Overrides --enum-field-as-literal.
You can pass the mapping either inline as JSON or as a path to a JSON file.
Usage
datamodel-codegen --input enum_field_as_literal_map.json --enum-field-as-literal-map '{"status": "literal"}' # (1)!
-
--enum-field-as-literal-map- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "EnumFieldAsLiteralMap",
"type": "object",
"properties": {
"status": {
"title": "Status",
"type": "string",
"enum": ["active", "inactive", "pending"]
},
"priority": {
"title": "Priority",
"type": "string",
"enum": ["high", "medium", "low"]
},
"category": {
"title": "Category",
"type": "string",
"enum": ["a", "b", "c"]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: enum_field_as_literal_map.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from typing import Literal
from pydantic import BaseModel, Field
class Priority(Enum):
high = 'high'
medium = 'medium'
low = 'low'
class Category(Enum):
a = 'a'
b = 'b'
c = 'c'
class EnumFieldAsLiteralMap(BaseModel):
status: Literal['active', 'inactive', 'pending'] | None = Field(
None, title='Status'
)
priority: Priority | None = Field(None, title='Priority')
category: Category | None = Field(None, title='Category')
--filter-literal-values¶
Keep only the values of a const or an enum that meet the constraints beside them.
JSON Schema validates a value against the enum and the keywords beside it, so {"enum": ["hello", "goodbye"],
"maxLength": 5} admits hello only. With --filter-literal-values, the Literal or the Enum of a const or
an enum holds the values that meet the minLength, maxLength, minimum, maximum, exclusiveMinimum,
exclusiveMaximum, multipleOf and pattern keywords beside them, as far as the generator can decide them (a
pattern only where every regular expression engine reads it alike). A schema none of whose values meets them
admits no value: it stays as written, with a warning. A field that writes a constraint itself, such as
Field(min_length=...), keeps the values that constraint checks. --omit-redundant-constraints includes this
check. Without the option, every value stays and the keywords are written beside the type.
Usage
-
--filter-literal-values- the option documented here
Examples
Input Schema:
openapi: "3.1.0"
components:
schemas:
Foo:
type: object
properties:
bar:
type: array
items:
enum:
- hello
- goodbye
maxLength: 5
minLength: 1
type: string
pattern: "^.*$"
maxItems: 3
Output:
# generated by datamodel-codegen:
# filename: max_items_enum.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field
class BarEnum(Enum):
hello = 'hello'
class Foo(BaseModel):
bar: list[BarEnum] | None = Field(None, max_length=3)
--ignore-enum-constraints¶
Ignore enum constraints and use base string type instead of Enum classes.
The --ignore-enum-constraints flag ignores enum constraints and uses
the base type (str) instead of generating Enum classes. This is useful
when you need flexibility in the values a field can accept beyond the
defined enum members.
Usage
-
--ignore-enum-constraints- the option documented here
Examples
Input Schema:
"Employee shift status"
enum EmployeeShiftStatus {
"not on shift"
NOT_ON_SHIFT
"on shift"
ON_SHIFT
}
enum Color {
RED
GREEN
BLUE
}
enum EnumWithOneField {
FIELD
}
Output:
# generated by datamodel-codegen:
# filename: enums.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import RootModel
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
String = TypeAliasType("String", str)
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class Color(RootModel[str]):
root: str
class EmployeeShiftStatus(RootModel[str]):
"""
Employee shift status
"""
root: str
class EnumWithOneField(RootModel[str]):
root: str
# generated by datamodel-codegen:
# filename: enums.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
String = TypeAliasType("String", str)
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class Color(Enum):
BLUE = 'BLUE'
GREEN = 'GREEN'
RED = 'RED'
class EmployeeShiftStatus(Enum):
"""
Employee shift status
"""
NOT_ON_SHIFT = 'NOT_ON_SHIFT'
ON_SHIFT = 'ON_SHIFT'
class EnumWithOneField(Enum):
FIELD = 'FIELD'
--import-overrides¶
Override modules for generated imports by symbol name.
The mapping applies to imports in generated output regardless of their original module, except for
__future__ imports. This is useful for routing typing helpers through a project compatibility module
across Python target versions.
Usage
datamodel-codegen --input datetime.json --output-model-type typing.TypedDict --target-python-version 3.10 --import-overrides '{"TypedDict": "my_project.typing_compat", "NotRequired": "my_project.typing_compat"}' # (1)!
-
--import-overrides- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"User": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "ken"
},
"birthDay": {
"type": "string",
"format": "date-time",
"example": "2016-08-29T09:12:33.001Z"
}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: datetime.json
# timestamp: 1985-10-26T08:21:00+00:00
from __future__ import annotations
from typing import Any, TypeAlias
from my_project.typing_compat import NotRequired, TypedDict
Model: TypeAlias = Any
class User(TypedDict):
name: NotRequired[str]
birthDay: NotRequired[str]
--intersect-allof-keywords¶
Combine the keywords of every part of an allOf, a $ref with siblings or an override.
JSON Schema applies the members of an allOf, a $ref and the keywords beside it, and a property that overrides
an inherited one all at once, so a value must meet every part. Without the option the keyword of the last part
wins where the parts disagree: the sibling of a $ref, the overriding property, the last member of an allOf.
With --intersect-allof-keywords, the tightest bound of the parts is written (maximum: 10 beside maximum: 20
keeps 10), an enum holds the values every part admits, a type the types every part admits, required the names
of every part, and the patterns of the parts are checked together. An allOf of value schemas at a root, an item
or a map value is one constraint schema in the same way, and a null member beside a type that excludes null is
dropped. Parts that no value meets together keep the earlier merge with a warning.
Usage
-
--intersect-allof-keywords- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Model",
"type": "object",
"properties": {
"c": {
"$ref": "#/$defs/Child"
}
},
"$defs": {
"Base": {
"type": "object",
"properties": {
"x": {
"type": "integer",
"maximum": 10
},
"e": {
"type": "string",
"enum": [
"a",
"b"
]
},
"y": {
"type": "integer",
"minimum": 0
}
}
},
"Child": {
"allOf": [
{
"$ref": "#/$defs/Base"
},
{
"type": "object",
"properties": {
"x": {
"maximum": 20
},
"e": {
"enum": [
"b",
"c"
]
},
"y": {
"maximum": 5
}
}
}
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: inherited_overrides.json
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field
class E(Enum):
a = 'a'
b = 'b'
class Base(BaseModel):
x: int | None = Field(None, le=10)
e: E | None = None
y: int | None = Field(None, ge=0)
class E1(Enum):
b = 'b'
class Child(Base):
x: int | None = Field(None, le=10)
e: E1 | None = None
y: int | None = Field(None, ge=0, le=5)
class Model(BaseModel):
c: Child | None = None
# generated by datamodel-codegen:
# filename: inherited_overrides.json
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field
class E(Enum):
a = 'a'
b = 'b'
class Base(BaseModel):
x: int | None = Field(None, le=10)
e: E | None = None
y: int | None = Field(None, ge=0)
class E1(Enum):
b = 'b'
c = 'c'
class Child(Base):
x: int | None = Field(None, le=20)
e: E1 | None = None
y: int | None = Field(None, ge=0, le=5)
class Model(BaseModel):
c: Child | None = None
--intersect-combined-schema-keywords¶
Combine the keywords beside an anyOf or oneOf with each branch, as JSON Schema does.
The keywords beside an anyOf or oneOf apply to every value, whichever branch it meets. Without the option each
branch is parsed with them merged in, and the branch's value of a keyword wins: minimum: 5 beside a branch with
minimum: 1 gives ge=1. With --intersect-combined-schema-keywords, which turns on --intersect-allof-keywords,
each branch is their intersection as --intersect-allof-keywords writes it: the tightest bound, the conjunction of
the patterns, the common multipleOf, the type and enum values both admit, and nested properties alike; the
nullable beside the anyOf stays with the branch. Where parts meet, an enum also loses the values the merged
type rejects. A branch whose keywords no value meets together keeps its earlier merge with a warning. Where an
anyOf and a oneOf stand side by side, a branch of one keeps the branches of the other whose type admits one of
its types, and a branch that keeps none is left out, unless every branch is. A property that overrides an inherited
one merges its properties name by name, so a nested property named default or nullable stays; an override that
narrows the inherited type (to null, to one of its types, or in a nested schema) is the intersection instead of
the inherited type; and under --allof-merge-mode none the type shape keeps the length of a closed tuple. An allOf
member reads the siblings of its $ref as a part where the dialect does (2019-09 and later, OpenAPI 3.1), a member
naming a $ref alias takes the alias's target as its base, and the union an allOf member's anyOf or oneOf gives
admits null where every part of the allOf does.
Option relationships:
- Implies:
--intersect-allof-keywordsenabled
Usage
-
--intersect-combined-schema-keywords- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Model",
"type": "object",
"$defs": {
"Code": {"type": "integer", "minimum": 1},
"Small": {"type": "integer"},
"SmallOrNull": {"type": ["integer", "null"]},
"NoneLeft": {"$ref": "#/$defs/Small", "enum": ["a", "b"]},
"NullLeft": {"$ref": "#/$defs/SmallOrNull", "enum": [null, "a"]},
"Nested": {
"type": "object",
"properties": {"a": {"type": "integer", "minimum": 5}},
"anyOf": [
{"properties": {"a": {"minimum": 1}, "b": {"type": "string"}}, "required": ["b"]},
{"required": ["a"]}
]
}
},
"properties": {
"bound": {"minimum": 5, "anyOf": [{"type": "integer", "minimum": 1}, {"type": "string"}]},
"length": {"maxLength": 3, "oneOf": [{"type": "string", "maxLength": 10}, {"type": "integer"}]},
"pattern": {"pattern": "^a", "anyOf": [{"type": "string", "pattern": "b$"}, {"type": "integer"}]},
"multiple": {"multipleOf": 2, "anyOf": [{"type": "integer", "multipleOf": 3}, {"type": "string"}]},
"typed": {"type": "string", "anyOf": [{"type": ["string", "integer"], "minLength": 1}, {"maxLength": 3}]},
"values": {"enum": ["a", "b", 1], "anyOf": [{"type": "string", "enum": ["b", "c"]}, {"type": "integer"}]},
"ref_branch": {"anyOf": [{"$ref": "#/$defs/Code", "minimum": 5}, {"type": "string"}]},
"ref_enum": {"$ref": "#/$defs/Small", "enum": [1, "a", 2], "x-enum-varnames": ["one", "letter", "two"]},
"dead": {"type": "string", "anyOf": [{"type": "integer"}, {"minLength": 1}]}
}
}
Output:
# generated by datamodel-codegen:
# filename: combined_branch_keywords.json
from __future__ import annotations
from enum import Enum, IntEnum
from pydantic import BaseModel, ConfigDict, RootModel, conint, constr
class Bound(RootModel[conint(ge=5)]):
root: conint(ge=5)
class Bound1(RootModel[str]):
root: str
class Length(RootModel[constr(max_length=3)]):
root: constr(max_length=3)
class Length1(RootModel[int]):
root: int
class Pattern(RootModel[str]):
model_config = ConfigDict(
regex_engine="python-re",
)
root: constr(pattern=r'\A(?=[\s\S]*?(?:^a))(?=[\s\S]*?(?:b$))')
class Pattern1(RootModel[int]):
root: int
class Multiple(RootModel[conint(multiple_of=6)]):
root: conint(multiple_of=6)
class Multiple1(RootModel[str]):
root: str
class Values(Enum):
b = 'b'
class Values1(IntEnum):
integer_1 = 1
class RefEnum(IntEnum):
one = 1
two = 2
class Model(BaseModel):
bound: Bound | Bound1 | None = None
length: Length | Length1 | None = None
pattern: Pattern | Pattern1 | None = None
multiple: Multiple | Multiple1 | None = None
typed: constr(min_length=1) | constr(max_length=3) | None = None
values: Values | Values1 | None = None
ref_branch: conint(ge=5) | str | None = None
ref_enum: RefEnum | None = None
dead: int | constr(min_length=1) | None = None
class Code(RootModel[conint(ge=1)]):
root: conint(ge=1)
class Small(RootModel[int]):
root: int
class SmallOrNull(RootModel[int | None]):
root: int | None
class NoneLeft(Enum):
a = 'a'
b = 'b'
class NullLeft(Enum):
NoneType_None = None
class Nested1(BaseModel):
a: conint(ge=5) | None = None
b: str
class Nested2(BaseModel):
a: conint(ge=5)
class Nested(RootModel[Nested1 | Nested2]):
root: Nested1 | Nested2
# generated by datamodel-codegen:
# filename: combined_branch_keywords.json
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, RootModel, conint, constr
class Bound(RootModel[conint(ge=1)]):
root: conint(ge=1)
class Bound1(RootModel[str]):
root: str
class Length(RootModel[constr(max_length=10)]):
root: constr(max_length=10)
class Length1(RootModel[int]):
root: int
class Pattern(RootModel[constr(pattern=r'b$')]):
root: constr(pattern=r'b$')
class Pattern1(RootModel[int]):
root: int
class Multiple(RootModel[conint(multiple_of=3)]):
root: conint(multiple_of=3)
class Multiple1(RootModel[str]):
root: str
class Values(Enum):
b = 'b'
class Values1(Enum):
a = 'a'
b = 'b'
integer_1 = 1
class RefEnum(Enum):
one = 1
letter = 'a'
two = 2
class Model(BaseModel):
bound: Bound | Bound1 | None = None
length: Length | Length1 | None = None
pattern: Pattern | Pattern1 | None = None
multiple: Multiple | Multiple1 | None = None
typed: constr(min_length=1) | int | constr(max_length=3) | None = None
values: Values | Values1 | None = None
ref_branch: conint(ge=5) | str | None = None
ref_enum: RefEnum | None = None
dead: int | constr(min_length=1) | None = None
class Code(RootModel[conint(ge=1)]):
root: conint(ge=1)
class Small(RootModel[int]):
root: int
class SmallOrNull(RootModel[int | None]):
root: int | None
class NoneLeft(Enum):
a = 'a'
b = 'b'
class NullLeft(Enum):
NoneType_None = None
a = 'a'
class Nested1(BaseModel):
a: conint(ge=1) | None = None
b: str
class Nested2(BaseModel):
a: conint(ge=5)
class Nested(RootModel[Nested1 | Nested2]):
root: Nested1 | Nested2
--keep-enum-member-values¶
Give an enum class a value base only when it keeps every member value.
--use-specialized-enum (IntEnum, StrEnum) and --use-subclass-enum ((T, Enum)) give an enum class the value
type of its schema type as a base. Without this option the base follows the schema type alone, as in 0.86.0, so a
member the base changes is written with the changed value: const branches [1, 2.5] make an IntEnum whose 2.5
becomes 2 (rejecting the schema-valid 2.5 and accepting 2), and ['a', 1] under --use-subclass-enum a
(str, Enum) holding '1'. With the option such an enum is a plain Enum that keeps the values as written; members
the base keeps, as 1.0 in an IntEnum or 1 in a (float, Enum), keep the base. msgspec keeps the 0.86.0 class
where it could not decode the plain Enum. A base that cannot hold a member at all, so that the class failed at
import ('a' in an IntEnum, a format: byte enum), gives a plain Enum either way.
Usage
-
--keep-enum-member-values- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "EnumValueBaseKinds",
"type": "object",
"properties": {
"str_then_int": {"oneOf": [{"const": "a"}, {"const": 1}]},
"int_then_str": {"oneOf": [{"const": 1}, {"const": "a"}]},
"int_then_float": {"oneOf": [{"const": 1}, {"const": 2.5}]},
"int_then_bool": {"oneOf": [{"const": 1}, {"const": true}]},
"numbers": {"type": "number", "enum": [1, 2.5]},
"integral_floats": {"type": "integer", "enum": [1.0, 2.0]},
"base64": {"type": "string", "format": "byte", "enum": ["YQ==", "Yg=="]},
"byte_counts": {"type": "string", "format": "byte", "enum": [1, 2]}
}
}
Output:
# generated by datamodel-codegen:
# filename: enum_value_base_kinds.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum, IntEnum
from pydantic import BaseModel
class StrThenInt(Enum):
a = 'a'
field_1 = 1
class IntThenStr(Enum):
integer_1 = 1
a = 'a'
class IntThenFloat(Enum):
integer_1 = 1
integer_2_5 = 2.5
class IntThenBool(IntEnum):
integer_1 = 1
integer_True = True
class Numbers(Enum):
number_1 = 1
number_2_5 = 2.5
class IntegralFloats(IntEnum):
integer_1_0 = 1.0
integer_2_0 = 2.0
class Base64(Enum):
YQ__ = 'YQ=='
Yg__ = 'Yg=='
class ByteCounts(Enum):
field_1 = 1
field_2 = 2
class EnumValueBaseKinds(BaseModel):
str_then_int: StrThenInt | None = None
int_then_str: IntThenStr | None = None
int_then_float: IntThenFloat | None = None
int_then_bool: IntThenBool | None = None
numbers: Numbers | None = None
integral_floats: IntegralFloats | None = None
base64: Base64 | None = None
byte_counts: ByteCounts | None = None
# generated by datamodel-codegen:
# filename: enum_value_base_kinds.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum, IntEnum
from pydantic import BaseModel
class StrThenInt(Enum):
a = 'a'
field_1 = 1
class IntThenStr(Enum):
integer_1 = 1
a = 'a'
class IntThenFloat(IntEnum):
integer_1 = 1
integer_2_5 = 2.5
class IntThenBool(IntEnum):
integer_1 = 1
integer_True = True
class Numbers(Enum):
number_1 = 1
number_2_5 = 2.5
class IntegralFloats(IntEnum):
integer_1_0 = 1.0
integer_2_0 = 2.0
class Base64(Enum):
YQ__ = 'YQ=='
Yg__ = 'Yg=='
class ByteCounts(Enum):
field_1 = 1
field_2 = 2
class EnumValueBaseKinds(BaseModel):
str_then_int: StrThenInt | None = None
int_then_str: IntThenStr | None = None
int_then_float: IntThenFloat | None = None
int_then_bool: IntThenBool | None = None
numbers: Numbers | None = None
integral_floats: IntegralFloats | None = None
base64: Base64 | None = None
byte_counts: ByteCounts | None = None
--no-use-closed-typed-dict¶
Disable PEP 728 TypedDict closed/extra_items generation.
Use this option for compatibility with type checkers that don't yet support PEP 728
(e.g., mypy). TypedDict will be generated without closed=True or extra_items.
Usage
datamodel-codegen --input typed_dict_closed.json --output-model-type typing.TypedDict --no-use-closed-typed-dict # (1)!
-
--no-use-closed-typed-dict- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "ClosedModel",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name"],
"additionalProperties": false
}
Output:
--no-use-specialized-enum¶
Disable specialized Enum classes for Python 3.11+ code generation.
The --no-use-specialized-enum flag prevents the generator from using
specialized Enum classes (StrEnum, IntEnum) when generating code for
Python 3.11+, falling back to standard Enum classes instead.
Related: --target-python-version, --use-specialized-enum, --use-subclass-enum
Usage
datamodel-codegen --input enums.graphql --target-python-version 3.11 --no-use-specialized-enum # (1)!
-
--no-use-specialized-enum- the option documented here
Examples
Input Schema:
{
"openapi": "3.0.2",
"components": {
"schemas": {
"ProcessingStatus": {
"title": "ProcessingStatus",
"enum": [
"COMPLETED",
"PENDING",
"FAILED"
],
"type": "string",
"description": "The processing status"
},
"ProcessingTask": {
"title": "ProcessingTask",
"type": "object",
"properties": {
"processing_status": {
"title": "Status of the task",
"allOf": [
{
"$ref": "#/components/schemas/ProcessingStatus"
}
],
"default": "COMPLETED"
}
}
},
}
},
"info": {
"title": "",
"version": ""
},
"paths": {}
}
Output:
# generated by datamodel-codegen:
# filename: subclass_enum.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field
class ProcessingStatus(Enum):
COMPLETED = 'COMPLETED'
PENDING = 'PENDING'
FAILED = 'FAILED'
class ProcessingTask(BaseModel):
processing_status: ProcessingStatus | None = Field(
'COMPLETED', title='Status of the task'
)
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"IntEnum": {
"type": "integer",
"enum": [
1,
2,
3
]
},
"FloatEnum": {
"type": "number",
"enum": [
1.1,
2.1,
3.1
]
},
"StrEnum": {
"type": "string",
"enum": [
"1",
"2",
"3"
]
},
"NonTypedEnum": {
"enum": [
"1",
"2",
"3"
]
},
"BooleanEnum": {
"type": "boolean",
"enum": [
true,
false
]
},
"UnknownEnum": {
"type": "unknown",
"enum": [
"a",
"b"
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: subclass_enum.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field
class IntEnum(Enum):
integer_1 = 1
integer_2 = 2
integer_3 = 3
class FloatEnum(Enum):
number_1_1 = 1.1
number_2_1 = 2.1
number_3_1 = 3.1
class StrEnum(Enum):
field_1 = '1'
field_2 = '2'
field_3 = '3'
class NonTypedEnum(Enum):
field_1 = '1'
field_2 = '2'
field_3 = '3'
class BooleanEnum(Enum):
boolean_True = True
boolean_False = False
class UnknownEnum(Enum):
a = 'a'
b = 'b'
class Model(BaseModel):
IntEnum_1: IntEnum | None = Field(None, alias='IntEnum')
FloatEnum_1: FloatEnum | None = Field(None, alias='FloatEnum')
StrEnum_1: StrEnum | None = Field(None, alias='StrEnum')
NonTypedEnum_1: NonTypedEnum | None = Field(None, alias='NonTypedEnum')
BooleanEnum_1: BooleanEnum | None = Field(None, alias='BooleanEnum')
UnknownEnum_1: UnknownEnum | None = Field(None, alias='UnknownEnum')
Input Schema:
"Employee shift status"
enum EmployeeShiftStatus {
"not on shift"
NOT_ON_SHIFT
"on shift"
ON_SHIFT
}
enum Color {
RED
GREEN
BLUE
}
enum EnumWithOneField {
FIELD
}
Output:
# generated by datamodel-codegen:
# filename: enums.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
String = TypeAliasType("String", str)
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class Color(Enum):
BLUE = 'BLUE'
GREEN = 'GREEN'
RED = 'RED'
class EmployeeShiftStatus(Enum):
"""
Employee shift status
"""
NOT_ON_SHIFT = 'NOT_ON_SHIFT'
ON_SHIFT = 'ON_SHIFT'
class EnumWithOneField(Enum):
FIELD = 'FIELD'
--no-use-standard-collections¶
Use typing.Dict/List instead of built-in dict/list for container types.
The --no-use-standard-collections flag generates typing module containers
(Dict, List) instead of built-in types. This is useful for older Python
versions or when explicit typing imports are preferred.
Related: --use-standard-collections
Usage
datamodel-codegen --input root_model_with_additional_properties.json --no-use-standard-collections # (1)!
-
--no-use-standard-collections- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "test.json",
"description": "test",
"type": "object",
"required": [
"test_id",
"test_ip",
"result",
"nested_object_result",
"nested_enum_result"
],
"properties": {
"test_id": {
"type": "string",
"description": "test ID"
},
"test_ip": {
"type": "string",
"description": "test IP"
},
"result": {
"type": "object",
"additionalProperties": {
"type": "integer"
}
},
"nested_object_result": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"status":{
"type": "integer"
}
},
"required": ["status"]
}
},
"nested_enum_result": {
"type": "object",
"additionalProperties": {
"enum": ["red", "green"]
}
},
"all_of_result" :{
"type" : "object",
"additionalProperties" :
{
"allOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"one_of_result" :{
"type" : "object",
"additionalProperties" :
{
"oneOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"any_of_result" :{
"type" : "object",
"additionalProperties" :
{
"anyOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"all_of_with_unknown_object" :{
"type" : "object",
"additionalProperties" :
{
"allOf" : [
{ "$ref" : "#/definitions/User" },
{ "description": "TODO" }
]
}
},
"objectRef": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/User"
}
},
"deepNestedObjectRef": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/User"
}
}
}
}
},
"definitions": {
"User": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: root_model_with_additional_properties.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from typing import Dict
from pydantic import BaseModel, Field
class NestedObjectResult(BaseModel):
status: int
class NestedEnumResult(Enum):
red = 'red'
green = 'green'
class OneOfResult(BaseModel):
description: str | None = None
class AnyOfResult(BaseModel):
description: str | None = None
class User(BaseModel):
name: str | None = None
class AllOfResult(User):
description: str | None = None
class Model(BaseModel):
test_id: str = Field(..., description='test ID')
test_ip: str = Field(..., description='test IP')
result: Dict[str, int]
nested_object_result: Dict[str, NestedObjectResult]
nested_enum_result: Dict[str, NestedEnumResult]
all_of_result: Dict[str, AllOfResult] | None = None
one_of_result: Dict[str, User | OneOfResult] | None = None
any_of_result: Dict[str, User | AnyOfResult] | None = None
all_of_with_unknown_object: Dict[str, User] | None = None
objectRef: Dict[str, User] | None = None
deepNestedObjectRef: Dict[str, Dict[str, Dict[str, User]]] | None = None
--no-use-union-operator¶
Use Union[X, Y] / Optional[X] instead of X | Y union operator.
The --no-use-union-operator flag generates union types using typing.Union
and typing.Optional instead of the | operator (PEP 604). This is useful
for older Python versions or when explicit typing imports are preferred.
Related: --use-union-operator
Usage
-
--no-use-union-operator- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "test.json",
"description": "test",
"type": "object",
"required": [
"test_id",
"test_ip",
"result",
"nested_object_result",
"nested_enum_result"
],
"properties": {
"test_id": {
"type": "string",
"description": "test ID"
},
"test_ip": {
"type": "string",
"description": "test IP"
},
"result": {
"type": "object",
"additionalProperties": {
"type": "integer"
}
},
"nested_object_result": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"status":{
"type": "integer"
}
},
"required": ["status"]
}
},
"nested_enum_result": {
"type": "object",
"additionalProperties": {
"enum": ["red", "green"]
}
},
"all_of_result" :{
"type" : "object",
"additionalProperties" :
{
"allOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"one_of_result" :{
"type" : "object",
"additionalProperties" :
{
"oneOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"any_of_result" :{
"type" : "object",
"additionalProperties" :
{
"anyOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"all_of_with_unknown_object" :{
"type" : "object",
"additionalProperties" :
{
"allOf" : [
{ "$ref" : "#/definitions/User" },
{ "description": "TODO" }
]
}
},
"objectRef": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/User"
}
},
"deepNestedObjectRef": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/User"
}
}
}
}
},
"definitions": {
"User": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: root_model_with_additional_properties.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from typing import Optional, Union
from pydantic import BaseModel, Field
class NestedObjectResult(BaseModel):
status: int
class NestedEnumResult(Enum):
red = 'red'
green = 'green'
class OneOfResult(BaseModel):
description: Optional[str] = None
class AnyOfResult(BaseModel):
description: Optional[str] = None
class User(BaseModel):
name: Optional[str] = None
class AllOfResult(User):
description: Optional[str] = None
class Model(BaseModel):
test_id: str = Field(..., description='test ID')
test_ip: str = Field(..., description='test IP')
result: dict[str, int]
nested_object_result: dict[str, NestedObjectResult]
nested_enum_result: dict[str, NestedEnumResult]
all_of_result: Optional[dict[str, AllOfResult]] = None
one_of_result: Optional[dict[str, Union[User, OneOfResult]]] = None
any_of_result: Optional[dict[str, Union[User, AnyOfResult]]] = None
all_of_with_unknown_object: Optional[dict[str, User]] = None
objectRef: Optional[dict[str, User]] = None
deepNestedObjectRef: Optional[dict[str, dict[str, dict[str, User]]]] = None
--output-date-class¶
Specify date class type for date schema fields.
The --output-date-class flag controls which date type to use for fields
with date format. Options include 'PastDate' for past dates only
or 'FutureDate' for future dates only. This is a Pydantic v2 only feature.
Usage
-
--output-date-class- the option documented here
Examples
Input Schema:
openapi: "3.0.0"
components:
schemas:
Event:
type: object
required:
- eventDate
properties:
eventDate:
type: string
format: date
example: 2023-12-25
Output:
--output-datetime-class¶
Specify datetime class type for date-time schema fields.
The --output-datetime-class flag controls which datetime type to use for fields
with date-time format. Options include 'AwareDatetime' for timezone-aware datetimes
or 'datetime' for standard Python datetime objects.
See also: Type Mappings and Custom Types
Usage
-
--output-datetime-class- the option documented here
Examples
Input Schema:
openapi: "3.0.0"
components:
schemas:
InventoryItem:
required:
# - id
# - name
- releaseDate
type: object
properties:
# id:
# type: string
# format: uuid
# example: d290f1ee-6c54-4b01-90e6-d701748f0851
# name:
# type: string
# example: Widget Adapter
releaseDate:
type: string
format: date-time
example: 2016-08-29T09:12:33.001Z
Output:
--read-allof-parents-in-mro-order¶
Read the allOf parents of every inherited schema in the order of the class bases.
A property that several bases declare takes the declaration of the first base in the method resolution order of the
generated class, the nearer one. With BaseFirst = allOf: [A, B] and B = allOf: [A, {p: maxLength 3}], the class
is BaseFirst(B, A), but the parents of the inner allOf were read in document order, so a subclass that redeclares
p took A's max_length=5 and accepted "abcd", which B rejects. With --read-allof-parents-in-mro-order it
takes B's max_length=3, whichever order the allOf lists A and B.
Related: --allof-merge-mode
Usage
datamodel-codegen --input allof_inherited_property_nearer_base.json --read-allof-parents-in-mro-order # (1)!
-
--read-allof-parents-in-mro-order- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"A": {
"type": "object",
"properties": {"p": {"type": "string", "maxLength": 5}, "q": {"type": "integer"}}
},
"B": {
"allOf": [{"$ref": "#/$defs/A"}, {"type": "object", "properties": {"p": {"type": "string", "maxLength": 3}}}]
},
"BaseFirst": {"allOf": [{"$ref": "#/$defs/A"}, {"$ref": "#/$defs/B"}]},
"DescendantFirst": {"allOf": [{"$ref": "#/$defs/B"}, {"$ref": "#/$defs/A"}]},
"FromBaseFirst": {
"allOf": [{"$ref": "#/$defs/BaseFirst"}, {"type": "object", "properties": {"p": {"minLength": 1}}, "required": ["p", "q"]}]
},
"FromDescendantFirst": {
"allOf": [
{"$ref": "#/$defs/DescendantFirst"},
{"type": "object", "properties": {"p": {"minLength": 1}}, "required": ["p", "q"]}
]
}
},
"type": "object",
"properties": {
"base_first": {"$ref": "#/$defs/FromBaseFirst"},
"descendant_first": {"$ref": "#/$defs/FromDescendantFirst"}
}
}
Output:
# generated by datamodel-codegen:
# filename: allof_inherited_property_nearer_base.json
from __future__ import annotations
from pydantic import BaseModel, constr
class A(BaseModel):
p: constr(max_length=5) | None = None
q: int | None = None
class B(A):
p: constr(max_length=3) | None = None
class BaseFirst(B, A):
pass
class DescendantFirst(B, A):
pass
class FromBaseFirst(BaseFirst):
p: constr(min_length=1, max_length=3)
q: int
class FromDescendantFirst(DescendantFirst):
p: constr(min_length=1, max_length=3)
q: int
class Model(BaseModel):
base_first: FromBaseFirst | None = None
descendant_first: FromDescendantFirst | None = None
# generated by datamodel-codegen:
# filename: allof_inherited_property_nearer_base.json
from __future__ import annotations
from pydantic import BaseModel, constr
class A(BaseModel):
p: constr(max_length=5) | None = None
q: int | None = None
class B(A):
p: constr(max_length=3) | None = None
class BaseFirst(B, A):
pass
class DescendantFirst(B, A):
pass
class FromBaseFirst(BaseFirst):
p: constr(min_length=1, max_length=5)
q: int
class FromDescendantFirst(DescendantFirst):
p: constr(min_length=1, max_length=3)
q: int
class Model(BaseModel):
base_first: FromBaseFirst | None = None
descendant_first: FromDescendantFirst | None = None
--read-const-beside-enum¶
Read a const beside an enum as JSON Schema does.
A const that admits some but not all values of the enum beside it narrows the schema to the admitted
values, while the enum class keeps every value as written. With --read-const-beside-enum, a value whose schema
names such an enum, a property, an item, a map value or key, a union branch or a $ref to a definition, is typed
by the const: Literal[<Enum>.<member>] when the members of the enum equal their values (IntEnum, StrEnum,
--use-subclass-enum), the const's own Literal, or None for a null const. A plain Enum, and any msgspec
enum, keeps the enum type and warns once per schema location that the other values are accepted. A schema whose
const is none of its enum values admits no value and is generated as written with a warning. Under
--use-single-value-enum-as-const, an enum that admits the const beside it, such as
{"enum": ["a", "b"], "const": "a"}, is read as that const without the enum class written beside it otherwise,
except one with nullable: true and a const other than null. Without the option, a const beside an enum is
ignored.
Usage
-
--read-const-beside-enum- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Positions",
"type": "object",
"properties": {
"property": {"type": "string", "enum": ["a", "b"], "const": "a"},
"propertySingle": {"type": "string", "enum": ["a"], "const": "a"},
"words": {"type": "array", "items": {"type": "string", "enum": ["a", "b"], "const": "b"}},
"counts": {"type": "object", "additionalProperties": {"type": "integer", "enum": [1, 2, 3], "const": 2}},
"branch": {"anyOf": [{"type": "string", "enum": ["a", "b"], "const": "a"}, {"type": "integer"}]},
"refSibling": {"$ref": "#/$defs/Switch", "const": "on"},
"keys": {"type": "object", "propertyNames": {"enum": ["a", "b"], "const": "a"}, "additionalProperties": {"type": "integer"}},
"refKeys": {"type": "object", "propertyNames": {"$ref": "#/$defs/Narrowed"}, "additionalProperties": {"type": "integer"}},
"definition": {"$ref": "#/$defs/Narrowed"},
"definitionSingle": {"$ref": "#/$defs/Single"},
"allOfDefinition": {"$ref": "#/$defs/AllOfNarrowed"},
"besideNull": {"$ref": "#/$defs/BesideNull"},
"constNull": {"$ref": "#/$defs/ConstNull"}
},
"$defs": {
"Switch": {"type": "string", "enum": ["on", "off"]},
"Narrowed": {
"type": "string",
"enum": ["a", "b", "c"],
"const": "b",
"x-enum-varnames": ["ALPHA", "BRAVO", "CHARLIE"],
"x-enum-descriptions": ["First.", "Second.", "Third."]
},
"Single": {"type": "string", "enum": ["a"], "const": "a"},
"AllOfNarrowed": {"allOf": [{"type": "string", "enum": ["a", "b"], "const": "b"}]},
"BesideNull": {"type": "string", "enum": ["a", null, "b"], "const": "b", "x-enum-varnames": ["ALPHA", "BRAVO"]},
"ConstNull": {"type": "string", "enum": ["a", null, "b"], "const": null}
}
}
Output:
# generated by datamodel-codegen:
# filename: enum_const_positions.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum, IntEnum
from typing import Literal
from pydantic import BaseModel, Field, RootModel
class Property(Enum):
a = 'a'
b = 'b'
class PropertySingle(Enum):
a = 'a'
class Word(Enum):
a = 'a'
b = 'b'
class Counts(IntEnum):
integer_1 = 1
integer_2 = 2
integer_3 = 3
class Branch(Enum):
a = 'a'
b = 'b'
class RefSibling(Enum):
on = 'on'
off = 'off'
class Switch(Enum):
on = 'on'
off = 'off'
class Narrowed(Enum):
ALPHA = 'a'
BRAVO = 'b'
CHARLIE = 'c'
class Single(Enum):
a = 'a'
class AllOfNarrowed(Enum):
a = 'a'
b = 'b'
class BesideNullEnum(Enum):
ALPHA = 'a'
BRAVO = 'b'
class BesideNull(RootModel[Literal['b'] | None]):
root: Literal['b'] | None = None
class ConstNullEnum(Enum):
a = 'a'
b = 'b'
class ConstNull(RootModel[None]):
root: None = Field(None)
class Positions(BaseModel):
property: Literal['a'] | None = None
propertySingle: Literal['a'] | None = None
words: list[Word] | None = None
counts: dict[str, Literal[Counts.integer_2]] | None = None
branch: Branch | int | None = None
refSibling: Literal['on'] | None = None
keys: dict[Literal['a'], int] | None = None
refKeys: dict[Narrowed, int] | None = None
definition: Narrowed | None = None
definitionSingle: Single | None = None
allOfDefinition: AllOfNarrowed | None = None
besideNull: BesideNull | None = None
constNull: ConstNull | None = None
--read-unevaluated-properties¶
Read a schema-valued unevaluatedProperties as additionalProperties.
Where no applicator (allOf, anyOf, oneOf, not, if, dependentSchemas, dependencies or a reference)
evaluates a property of the object in place, the keys unevaluatedProperties evaluates are exactly those that
additionalProperties would, so its schema types the extra keys of a model (__pydantic_extra__: Dict[str, str])
and makes an object without properties a map (RootModel[dict[str, int]]). The schema object as written decides:
the models built from its branches keep the extra keys untyped where its applicators evaluate properties. Without
the option the extra keys are allowed untyped, as in 0.86.0.
Usage
-
--read-unevaluated-properties- the option documented here
Examples
Input Schema:
{
"$id": "https://example.com/test.schema.json",
"title": "Resource",
"type": "object",
"properties": {
"name": { "type": "string" }
},
"required": ["name"],
"unevaluatedProperties": {
"type": "string"
}
}
Output:
# generated by datamodel-codegen:
# filename: unevaluated_properties_schema.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Dict
from pydantic import BaseModel, ConfigDict
class Resource(BaseModel):
model_config = ConfigDict(
extra='allow',
)
__annotations__ = {
'__pydantic_extra__': Dict[str, str],
}
name: str
--strict-types¶
Enable strict type validation for specified Python types.
The --strict-types option enforces stricter type checking by preventing implicit type coercion for the specified types (str, bytes, int, float, bool). This generates StrictStr, StrictBytes, StrictInt, StrictFloat, and StrictBool types in Pydantic models, ensuring values match exactly without automatic conversion.
See also: Type Mappings and Custom Types
Usage
-
--strict-types- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "User",
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "ken"
},
"age": {
"type": "integer"
},
"salary": {
"type": "integer",
"minimum": 0
},
"debt" : {
"type": "integer",
"maximum": 0
},
"loan" : {
"type": "number",
"maximum": 0
},
"tel": {
"type": "string",
"pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
},
"height": {
"type": "number",
"minimum": 0
},
"weight": {
"type": "number",
"minimum": 0
},
"score": {
"type": "number",
"minimum": 1e-08
},
"active": {
"type": "boolean"
},
"photo": {
"type": "string",
"format": "binary",
"minLength": 100
}
}
}
Output:
# generated by datamodel-codegen:
# filename: strict_types.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import (
BaseModel,
Field,
StrictBool,
StrictInt,
StrictStr,
conbytes,
confloat,
conint,
constr,
)
class User(BaseModel):
name: StrictStr | None = Field(None, examples=['ken'])
age: StrictInt | None = None
salary: conint(ge=0, strict=True) | None = None
debt: conint(le=0, strict=True) | None = None
loan: confloat(le=0.0, strict=True) | None = None
tel: constr(
pattern=r'^(\([0-9]{3}\))?[0-9]{3}-[0-9]{4}$', strict=True
) | None = None
height: confloat(ge=0.0, strict=True) | None = None
weight: confloat(ge=0.0, strict=True) | None = None
score: confloat(ge=1e-08, strict=True) | None = None
active: StrictBool | None = None
photo: conbytes(min_length=100, strict=True) | None = None
--type-mappings¶
Override default type mappings for schema formats.
The --type-mappings flag configures the code generation behavior.
See also: Type Mappings and Custom Types
Usage
datamodel-codegen --input type_mappings.json --output-model-type pydantic_v2.BaseModel --type-mappings binary=string # (1)!
-
--type-mappings- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "BlobModel",
"type": "object",
"properties": {
"content": {
"type": "string",
"format": "binary",
"description": "Binary content that should be mapped to string"
},
"data": {
"type": "string",
"format": "byte",
"description": "Base64 encoded data"
},
"name": {
"type": "string",
"description": "Regular string field"
}
},
"required": ["content", "data", "name"]
}
Output:
# generated by datamodel-codegen:
# filename: type_mappings.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import Base64Str, BaseModel, Field
class BlobModel(BaseModel):
content: str = Field(
..., description='Binary content that should be mapped to string'
)
data: Base64Str = Field(..., description='Base64 encoded data')
name: str = Field(..., description='Regular string field')
--type-overrides¶
Replace schema model types with custom Python types via JSON mapping.
This option is useful for importing models from external libraries (like geojson-pydantic)
instead of generating them.
Override Formats:
| Format | Description |
|---|---|
{"ModelName": "package.Type"} |
Model-level: Skip generation; replace field and inheritance refs |
{"Model.field": "package.Type"} |
Scoped: Override only specific field in specific model |
Common Use Cases:
| Use Case | Example Override |
|---|---|
| GeoJSON types | {"Feature": "geojson_pydantic.Feature"} |
| Custom datetime | {"Timestamp": "pendulum.DateTime"} |
| MongoDB ObjectId | {"ObjectId": "bson.ObjectId"} |
| Custom validators | {"Email": "my_app.types.ValidatedEmail"} |
Usage
datamodel-codegen --input type_overrides_test.json --type-overrides '{"CustomType": "my_app.types.CustomType"}' # (1)!
-
--type-overrides- the option documented here
Model-level overrides skip generation
When you specify a model-level override (without a dot in the key), the generator will
skip generating that model entirely and import it from the specified package instead.
References to that model are replaced in field annotations and allOf inheritance base classes.
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"CustomType": {"type": "string"},
"User": {
"type": "object",
"properties": {
"id": {"type": "integer"},
"custom": {"$ref": "#/definitions/CustomType"}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: type_overrides_test.json
# timestamp: 1985-10-26T08:21:00+00:00
from __future__ import annotations
from typing import Any
from my_app.types import CustomType
from pydantic import BaseModel, RootModel
class Model(RootModel[Any]):
root: Any
class User(BaseModel):
id: int | None = None
custom: CustomType | None = None
--type-overrides-replace-whole-type¶
Make every --type-overrides value of a field replace the field's whole type.
A class path of --type-overrides names the type of the whole field, but without this option the field keeps the dict
of an object map around it: {"M.f": "builtins.dict"} on a map of integers writes dict[str, dict], which rejects
{"a": 1}, valid for the schema, and decimal.Decimal writes a dict of Decimal values. With it the class replaces
the map itself (dict, Decimal), as an annotation such as dict[str, int] already does, and a propertyNames key
type leaves with the map.
The item counts of an array and the property counts of a map that an override replaces stay only where the new type
counts the same: a sequence class its items (builtins.tuple), a mapping class its keys (builtins.dict,
collections.abc.Mapping), or a type the generator cannot classify. Without the option they stay whatever the new type
is: a str in place of an array with maxItems limits the length of the string (notes), and typing.Any in place of
an array with minItems checks the length of every value and raises TypeError for one without a length. A count the
new type does not count is left out with a warning.
Usage
datamodel-codegen --input type_overrides_replace_whole_type.json --type-overrides '{"Inventory.counts": "builtins.dict", "Inventory.sized": "builtins.dict", "Inventory.amounts": "typing.Any", "Inventory.keyed": "collections.abc.Mapping", "Inventory.labels": "dict[str, str]", "Inventory.tags": "builtins.tuple", "Inventory.notes": "builtins.str", "Inventory.code": "builtins.bytes"}' --type-overrides-replace-whole-type # (1)!
-
--type-overrides-replace-whole-type- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Inventory",
"type": "object",
"properties": {
"counts": {"type": "object", "additionalProperties": {"type": "integer"}},
"sized": {"type": "object", "additionalProperties": {"type": "integer"}, "minProperties": 1},
"amounts": {"type": "object", "additionalProperties": {"type": "number"}, "maxProperties": 2},
"keyed": {"type": "object", "additionalProperties": {"type": "string"}, "propertyNames": {"maxLength": 2}},
"labels": {"type": "object", "additionalProperties": {"type": "string"}, "minProperties": 1},
"tags": {"type": "array", "items": {"type": "string"}, "minItems": 1},
"notes": {"type": "array", "items": {"type": "string"}, "maxItems": 3},
"code": {"type": "string", "minLength": 2}
}
}
Output:
# generated by datamodel-codegen:
# filename: type_overrides_replace_whole_type.json
from __future__ import annotations
from builtins import bytes, dict, str, tuple
from collections.abc import Mapping
from typing import Any
from pydantic import BaseModel, Field
class Inventory(BaseModel):
counts: dict | None = None
sized: dict | None = Field(None, min_length=1)
amounts: Any | None = None
keyed: Mapping | None = None
labels: dict[str, str] | None = Field(None, min_length=1)
tags: tuple | None = Field(None, min_length=1)
notes: str | None = None
code: bytes | None = None
# generated by datamodel-codegen:
# filename: type_overrides_replace_whole_type.json
from __future__ import annotations
from builtins import bytes, dict, str, tuple
from collections.abc import Mapping
from typing import Any
from pydantic import BaseModel, Field, constr
class Inventory(BaseModel):
counts: dict[str, dict] | None = None
sized: dict[str, dict] | None = Field(None, min_length=1)
amounts: dict[str, Any] | None = Field(None, max_length=2)
keyed: dict[constr(max_length=2), Mapping] | None = None
labels: dict[str, str] | None = Field(None, min_length=1)
tags: tuple | None = Field(None, min_length=1)
notes: str | None = Field(None, max_length=3)
code: bytes | None = None
--use-annotated¶
Use typing.Annotated for Field() with constraints.
The --use-annotated flag generates Field definitions using typing.Annotated
syntax instead of default values. This also enables --field-constraints.
--use-annotated alone does not preserve uniqueItems: true as set semantics.
Use --use-unique-items-as-set when you need the
generated type to enforce uniqueness for array schemas.
Related: --field-constraints
See also: Python Version Compatibility
Option relationships:
- Implies:
--field-constraintsenabled
Usage
datamodel-codegen --input annotated.graphql --output-model-type pydantic_v2.BaseModel --use-annotated # (1)!
-
--use-annotated- the option documented here
Examples
Input Schema:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
minimum: 0
maximum: 100
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
components:
schemas:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
minimum: 0
maximum: 9223372036854775807
name:
type: string
maxLength: 256
tag:
type: string
maxLength: 64
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
maxItems: 10
minItems: 1
uniqueItems: true
UID:
type: integer
minimum: 0
Users:
type: array
items:
required:
- id
- name
- uid
properties:
id:
type: integer
format: int64
minimum: 0
name:
type: string
maxLength: 256
tag:
type: string
maxLength: 64
uid:
$ref: '#/components/schemas/UID'
phones:
type: array
items:
type: string
minLength: 3
maxItems: 10
fax:
type: array
items:
type: string
minLength: 3
height:
type:
- integer
- number
minimum: 1
maximum: 300
weight:
type:
- number
- integer
minimum: 1.0
maximum: 1000.0
age:
type: integer
minimum: 0.0
maximum: 200.0
exclusiveMinimum: true
rating:
type: number
minimum: 0
exclusiveMinimum: true
maximum: 5
Id:
type: string
Rules:
type: array
items:
type: string
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
apis:
type: array
items:
type: object
properties:
apiKey:
type: string
description: To be used as a dataset parameter value
apiVersionNumber:
type: string
description: To be used as a version parameter value
apiUrl:
type: string
format: uri
minLength: 1
description: "The URL describing the dataset's fields"
apiDocumentationUrl:
type: string
format: uri
description: A URL to the API console for each API
Event:
type: object
properties:
name:
type: string
Result:
type: object
properties:
event:
$ref: '#/components/schemas/Event'
Output:
# generated by datamodel-codegen:
# filename: api_constrained.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Annotated
from pydantic import AnyUrl, BaseModel, Field, RootModel
class Pet(BaseModel):
id: Annotated[int, Field(ge=0, le=9223372036854775807)]
name: Annotated[str, Field(max_length=256)]
tag: Annotated[str | None, Field(max_length=64)] = None
class Pets(RootModel[list[Pet]]):
root: Annotated[list[Pet], Field(max_length=10, min_length=1)]
class UID(RootModel[int]):
root: Annotated[int, Field(ge=0)]
class Phone(RootModel[str]):
root: Annotated[str, Field(min_length=3)]
class FaxItem(RootModel[str]):
root: Annotated[str, Field(min_length=3)]
class User(BaseModel):
id: Annotated[int, Field(ge=0)]
name: Annotated[str, Field(max_length=256)]
tag: Annotated[str | None, Field(max_length=64)] = None
uid: UID
phones: Annotated[list[Phone] | None, Field(max_length=10)] = None
fax: list[FaxItem] | None = None
height: Annotated[int | float | None, Field(ge=1.0, le=300.0)] = None
weight: Annotated[float | int | None, Field(ge=1.0, le=1000.0)] = None
age: Annotated[int | None, Field(gt=0, le=200)] = None
rating: Annotated[float | None, Field(gt=0.0, le=5.0)] = None
class Users(RootModel[list[User]]):
root: list[User]
class Id(RootModel[str]):
root: str
class Rules(RootModel[list[str]]):
root: list[str]
class Error(BaseModel):
code: int
message: str
class Api(BaseModel):
apiKey: Annotated[
str | None, Field(description='To be used as a dataset parameter value')
] = None
apiVersionNumber: Annotated[
str | None, Field(description='To be used as a version parameter value')
] = None
apiUrl: Annotated[
AnyUrl | None, Field(description="The URL describing the dataset's fields")
] = None
apiDocumentationUrl: Annotated[
AnyUrl | None, Field(description='A URL to the API console for each API')
] = None
class Apis(RootModel[list[Api]]):
root: list[Api]
class Event(BaseModel):
name: str | None = None
class Result(BaseModel):
event: Event | None = None
Input Schema:
type A {
field: String!
optionalField: String
listField: [String!]!
listOptionalField: [String]!
optionalListField: [String!]
optionalListOptionalField: [String]
listListField:[[String!]!]!
}
Output:
# generated by datamodel-codegen:
# filename: annotated.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Annotated, Literal
from pydantic import BaseModel, Field
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
String = TypeAliasType("String", str)
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class A(BaseModel):
field: String
listField: list[String]
listListField: list[list[String]]
listOptionalField: list[String | None]
optionalField: String | None = None
optionalListField: list[String] | None = None
optionalListOptionalField: list[String | None] | None = None
typename__: Annotated[Literal['A'] | None, Field(alias='__typename')] = 'A'
--use-bytes-for-content-media-type¶
Type an OpenAPI string with a contentMediaType and no contentEncoding as bytes.
OpenAPI 3.1 writes raw binary content, such as an uploaded image, as a string with a contentMediaType and no
contentEncoding, in place of 3.0's format: binary, and the generated clients and servers send and receive such a
string as a file. Without this option the models type it str, so a generated server refuses every upload that is
not UTF-8. With it the string is bytes, as a format: binary string is, at a property, an item, a nullable property
and a root, with its length constraints; a string with a contentEncoding or a format of its own keeps its type.
Usage
-
--use-bytes-for-content-media-type- the option documented here
Examples
Input Schema:
openapi: 3.1.0
info:
title: Raw binary content named by content media types
version: "1"
paths: {}
components:
schemas:
Upload:
type: object
required: [image]
properties:
image: {type: string, contentMediaType: image/png}
limited: {type: string, contentMediaType: text/plain, maxLength: 8}
images: {type: array, items: {type: string, contentMediaType: image/png}}
nullable: {type: [string, "null"], contentMediaType: application/pdf}
picture: {$ref: "#/components/schemas/Picture"}
encoded: {type: string, contentMediaType: image/png, contentEncoding: base64}
email: {type: string, format: email, contentMediaType: text/plain}
text: {type: string}
Picture:
type: string
contentMediaType: image/jpeg
Output:
# generated by datamodel-codegen:
# filename: content_media_type_bytes.yaml
from __future__ import annotations
from pydantic import BaseModel, EmailStr, Field, RootModel, conbytes
class Picture(RootModel[bytes]):
root: bytes = Field(..., json_schema_extra={'contentMediaType': 'image/jpeg'})
class Upload(BaseModel):
image: bytes = Field(..., json_schema_extra={'contentMediaType': 'image/png'})
limited: conbytes(max_length=8) | None = Field(
None, json_schema_extra={'contentMediaType': 'text/plain'}
)
images: list[bytes] | None = None
nullable: bytes | None = Field(
None, json_schema_extra={'contentMediaType': 'application/pdf'}
)
picture: Picture | None = None
encoded: str | None = Field(
None,
json_schema_extra={'contentMediaType': 'image/png', 'contentEncoding': 'base64'},
)
email: EmailStr | None = Field(
None, json_schema_extra={'contentMediaType': 'text/plain'}
)
text: str | None = None
# generated by datamodel-codegen:
# filename: content_media_type_bytes.yaml
from __future__ import annotations
from pydantic import BaseModel, EmailStr, Field, RootModel, constr
class Picture(RootModel[str]):
root: str = Field(..., json_schema_extra={'contentMediaType': 'image/jpeg'})
class Upload(BaseModel):
image: str = Field(..., json_schema_extra={'contentMediaType': 'image/png'})
limited: constr(max_length=8) | None = Field(
None, json_schema_extra={'contentMediaType': 'text/plain'}
)
images: list[str] | None = None
nullable: str | None = Field(
None, json_schema_extra={'contentMediaType': 'application/pdf'}
)
picture: Picture | None = None
encoded: str | None = Field(
None,
json_schema_extra={'contentMediaType': 'image/png', 'contentEncoding': 'base64'},
)
email: EmailStr | None = Field(
None, json_schema_extra={'contentMediaType': 'text/plain'}
)
text: str | None = None
--use-closed-typed-dict¶
Generate TypedDict with PEP 728 closed/extra_items (default: enabled).
When enabled (default), generates TypedDict with PEP 728 closed=True or extra_items
parameters based on additionalProperties constraints in the schema.
Usage
datamodel-codegen --input typed_dict_closed.json --output-model-type typing.TypedDict --use-closed-typed-dict # (1)!
-
--use-closed-typed-dict- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "ClosedModel",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name"],
"additionalProperties": false
}
Output:
--use-decimal-for-multiple-of¶
Generate Decimal types for fields with multipleOf constraint.
The --use-decimal-for-multiple-of flag generates condecimal or Decimal
types for numeric fields that have a multipleOf constraint. This ensures
precise decimal arithmetic when validating values against the constraint.
See also: Type Mappings and Custom Types
Usage
-
--use-decimal-for-multiple-of- the option documented here
Examples
Input Schema:
{
"type": "object",
"properties": {
"price": {
"type": "number",
"multipleOf": 0.01,
"minimum": 0,
"maximum": 99999.99
},
"quantity": {
"type": "number",
"multipleOf": 0.1
},
"rate": {
"type": "number",
"multipleOf": 0.001,
"exclusiveMinimum": 0,
"exclusiveMaximum": 1
},
"simple_float": {
"type": "number",
"minimum": 0,
"maximum": 100
}
}
}
Output:
# generated by datamodel-codegen:
# filename: use_decimal_for_multiple_of.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from decimal import Decimal
from pydantic import BaseModel, condecimal, confloat
class Model(BaseModel):
price: (
condecimal(ge=Decimal('0'), le=Decimal('99999.99'), multiple_of=Decimal('0.01'))
| None
) = None
quantity: condecimal(multiple_of=Decimal('0.1')) | None = None
rate: (
condecimal(multiple_of=Decimal('0.001'), lt=Decimal('1.0'), gt=Decimal('0.0'))
| None
) = None
simple_float: confloat(ge=0.0, le=100.0) | None = None
--use-decimal-in-field-forms¶
Write Decimal for a number with multipleOf in the field forms too.
Under --use-decimal-for-multiple-of, the field forms (--field-constraints, --use-annotated) write a float with
the constraints in Field(), which accepts numbers that are no multiples within the float tolerance, such as
0.0100000001 for multipleOf: 0.01. With this option they write a Decimal with the constraints in Field()
instead, at a property, an item, a map value and a root, which rejects them as condecimal does. Under
--strict-types float the Decimal is strict: condecimal(..., strict=True), or strict=True among the Field()
arguments.
Usage
datamodel-codegen --input decimal_multiple_of_field_forms.json --use-decimal-for-multiple-of --use-annotated --use-decimal-in-field-forms # (1)!
-
--use-decimal-in-field-forms- the option documented here
Examples
Input Schema:
{
"title": "DecimalMultipleOfFieldForms",
"type": "object",
"properties": {
"amount": {"type": "number", "multipleOf": 0.01, "minimum": 0, "maximum": 1000000},
"opt": {"type": ["number", "null"], "multipleOf": 0.5, "minimum": -1000000, "maximum": 1000000},
"maxed": {"type": "number", "multipleOf": 0.1, "minimum": -1000000, "maximum": 10},
"inty": {"type": "integer", "multipleOf": 2},
"arr": {"type": "array", "items": {"type": "number", "multipleOf": 0.01, "minimum": -1000000, "maximum": 1000000}},
"mapv": {"type": "object", "additionalProperties": {"type": "number", "multipleOf": 0.01, "minimum": -1000000, "maximum": 1000000}},
"rate": {"$ref": "#/$defs/Rate"},
"plainf": {"type": "number", "minimum": 0}
},
"required": ["amount"],
"$defs": {"Rate": {"type": "number", "multipleOf": 0.001, "exclusiveMinimum": 0, "maximum": 1000000}}
}
Output:
# generated by datamodel-codegen:
# filename: decimal_multiple_of_field_forms.json
from __future__ import annotations
from decimal import Decimal
from typing import Annotated
from pydantic import BaseModel, Field, RootModel
from typing_extensions import TypeAliasType
class ArrItem(RootModel[Decimal]):
root: Annotated[Decimal, Field(ge=-1000000, le=1000000, multiple_of=0.01)]
MapvAdditionalProperty = TypeAliasType(
"MapvAdditionalProperty",
Annotated[Decimal, Field(ge=-1000000, le=1000000, multiple_of=0.01)],
)
class Rate(RootModel[Decimal]):
root: Annotated[Decimal, Field(gt=0, le=1000000, multiple_of=0.001)]
class DecimalMultipleOfFieldForms(BaseModel):
amount: Annotated[Decimal, Field(ge=0, le=1000000, multiple_of=0.01)]
opt: Annotated[Decimal | None, Field(ge=-1000000, le=1000000, multiple_of=0.5)] = (
None
)
maxed: Annotated[Decimal | None, Field(ge=-1000000, le=10, multiple_of=0.1)] = None
inty: Annotated[int | None, Field(multiple_of=2)] = None
arr: list[ArrItem] | None = None
mapv: dict[str, MapvAdditionalProperty] | None = None
rate: Rate | None = None
plainf: Annotated[float | None, Field(ge=0.0)] = None
# generated by datamodel-codegen:
# filename: decimal_multiple_of_field_forms.json
from __future__ import annotations
from typing import Annotated
from pydantic import BaseModel, Field, RootModel
from typing_extensions import TypeAliasType
class ArrItem(RootModel[float]):
root: Annotated[float, Field(ge=-1000000.0, le=1000000.0, multiple_of=0.01)]
MapvAdditionalProperty = TypeAliasType(
"MapvAdditionalProperty",
Annotated[float, Field(ge=-1000000.0, le=1000000.0, multiple_of=0.01)],
)
class Rate(RootModel[float]):
root: Annotated[float, Field(gt=0.0, le=1000000.0, multiple_of=0.001)]
class DecimalMultipleOfFieldForms(BaseModel):
amount: Annotated[float, Field(ge=0.0, le=1000000.0, multiple_of=0.01)]
opt: Annotated[
float | None, Field(ge=-1000000.0, le=1000000.0, multiple_of=0.5)
] = None
maxed: Annotated[float | None, Field(ge=-1000000.0, le=10.0, multiple_of=0.1)] = (
None
)
inty: Annotated[int | None, Field(multiple_of=2)] = None
arr: list[ArrItem] | None = None
mapv: dict[str, MapvAdditionalProperty] | None = None
rate: Rate | None = None
plainf: Annotated[float | None, Field(ge=0.0)] = None
--use-encoded-str-for-constrained-base64¶
Check the constraints of a format: byte string on its base64 text in the field forms.
JSON Schema checks pattern, minLength and maxLength of a format: byte string on the base64 text. The field
forms write Annotated[Base64Str, Field(...)] (--use-annotated) or, for an optional field, Base64Str | None =
Field(...) (--field-constraints), and Pydantic checks such constraints on the decoded text: maxLength: 8 accepts
the 12 characters of YWFhYWFhYQ==, which decode to 7. With this option the string is written
Annotated[str, Field(...), EncodedStr(encoder=Base64Encoder)], which Pydantic 2.10 or later checks on the text before
decoding it, at a property, an item, a map value, a root and a union member; Pydantic before 2.10 checks none of these
forms on the text, and a target Pydantic older than 2.10 warns so.
Usage
datamodel-codegen --input encoded_str_for_constrained_base64.json --use-annotated --use-encoded-str-for-constrained-base64 # (1)!
-
--use-encoded-str-for-constrained-base64- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "EncodedStrForConstrainedBase64",
"type": "object",
"required": ["required"],
"properties": {
"pattern": {"type": "string", "format": "byte", "pattern": "^Y"},
"lengths": {"type": "string", "format": "byte", "minLength": 4, "maxLength": 8},
"required": {"type": "string", "format": "byte", "minLength": 4},
"nullable": {"type": ["string", "null"], "format": "byte", "maxLength": 8},
"plain": {"type": "string", "format": "byte"},
"items": {"type": "array", "items": {"type": "string", "format": "byte", "maxLength": 8}},
"values": {"type": "object", "additionalProperties": {"type": "string", "format": "byte", "pattern": "^Y"}},
"ref": {"$ref": "#/$defs/Short"},
"member": {"anyOf": [{"type": "string", "format": "byte", "maxLength": 8}, {"type": "integer"}]},
"branch": {"type": ["array", "string"], "format": "byte", "maxLength": 8, "items": {"type": "integer"}}
},
"$defs": {
"Short": {"type": "string", "format": "byte", "maxLength": 8}
}
}
Output:
# generated by datamodel-codegen:
# filename: encoded_str_for_constrained_base64.json
from __future__ import annotations
from typing import Annotated
from pydantic import Base64Encoder, Base64Str, BaseModel, EncodedStr, Field, RootModel
from typing_extensions import TypeAliasType
class Item(
RootModel[Annotated[str, Field(max_length=8), EncodedStr(encoder=Base64Encoder)]]
):
root: Annotated[str, Field(max_length=8), EncodedStr(encoder=Base64Encoder)]
ValuesAdditionalProperty = TypeAliasType(
"ValuesAdditionalProperty",
Annotated[str, Field(pattern=r'^Y'), EncodedStr(encoder=Base64Encoder)],
)
class Member(
RootModel[Annotated[str, Field(max_length=8), EncodedStr(encoder=Base64Encoder)]]
):
root: Annotated[str, Field(max_length=8), EncodedStr(encoder=Base64Encoder)]
BranchString = TypeAliasType(
"BranchString",
Annotated[str, Field(max_length=8), EncodedStr(encoder=Base64Encoder)],
)
class Short(
RootModel[Annotated[str, Field(max_length=8), EncodedStr(encoder=Base64Encoder)]]
):
root: Annotated[str, Field(max_length=8), EncodedStr(encoder=Base64Encoder)]
class EncodedStrForConstrainedBase64(BaseModel):
pattern: (
Annotated[str, Field(pattern=r'^Y'), EncodedStr(encoder=Base64Encoder)] | None
) = None
lengths: (
Annotated[
str, Field(min_length=4, max_length=8), EncodedStr(encoder=Base64Encoder)
]
| None
) = None
required: Annotated[str, Field(min_length=4), EncodedStr(encoder=Base64Encoder)]
nullable: (
Annotated[str, Field(max_length=8), EncodedStr(encoder=Base64Encoder)] | None
) = None
plain: Base64Str | None = None
items: list[Item] | None = None
values: dict[str, ValuesAdditionalProperty] | None = None
ref: Short | None = None
member: Member | int | None = None
branch: BranchString | list[int] | None = None
# generated by datamodel-codegen:
# filename: encoded_str_for_constrained_base64.json
from __future__ import annotations
from typing import Annotated
from pydantic import Base64Str, BaseModel, Field, RootModel
from typing_extensions import TypeAliasType
class Item(RootModel[Base64Str]):
root: Annotated[Base64Str, Field(max_length=8)]
ValuesAdditionalProperty = TypeAliasType(
"ValuesAdditionalProperty", Annotated[Base64Str, Field(pattern='^Y')]
)
class Member(RootModel[Base64Str]):
root: Annotated[Base64Str, Field(max_length=8)]
BranchString = TypeAliasType("BranchString", Annotated[Base64Str, Field(max_length=8)])
class Short(RootModel[Base64Str]):
root: Annotated[Base64Str, Field(max_length=8)]
class EncodedStrForConstrainedBase64(BaseModel):
pattern: Annotated[Base64Str | None, Field(pattern='^Y')] = None
lengths: Annotated[Base64Str | None, Field(max_length=8, min_length=4)] = None
required: Annotated[Base64Str, Field(min_length=4)]
nullable: Annotated[Base64Str | None, Field(max_length=8)] = None
plain: Base64Str | None = None
items: list[Item] | None = None
values: dict[str, ValuesAdditionalProperty] | None = None
ref: Short | None = None
member: Member | int | None = None
branch: BranchString | list[int] | None = None
--use-generic-container-types¶
Use generic container types (Sequence, Mapping) for type hinting.
The --use-generic-container-types flag generates abstract container types
(Sequence, Mapping, FrozenSet) instead of concrete types (list, dict, set).
If --use-standard-collections is set, imports from collections.abc;
otherwise imports from typing.
Related: --use-standard-collections
See also: Python Version Compatibility
Usage
datamodel-codegen --input root_model_with_additional_properties.json --use-generic-container-types # (1)!
-
--use-generic-container-types- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "test.json",
"description": "test",
"type": "object",
"required": [
"test_id",
"test_ip",
"result",
"nested_object_result",
"nested_enum_result"
],
"properties": {
"test_id": {
"type": "string",
"description": "test ID"
},
"test_ip": {
"type": "string",
"description": "test IP"
},
"result": {
"type": "object",
"additionalProperties": {
"type": "integer"
}
},
"nested_object_result": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"status":{
"type": "integer"
}
},
"required": ["status"]
}
},
"nested_enum_result": {
"type": "object",
"additionalProperties": {
"enum": ["red", "green"]
}
},
"all_of_result" :{
"type" : "object",
"additionalProperties" :
{
"allOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"one_of_result" :{
"type" : "object",
"additionalProperties" :
{
"oneOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"any_of_result" :{
"type" : "object",
"additionalProperties" :
{
"anyOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"all_of_with_unknown_object" :{
"type" : "object",
"additionalProperties" :
{
"allOf" : [
{ "$ref" : "#/definitions/User" },
{ "description": "TODO" }
]
}
},
"objectRef": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/User"
}
},
"deepNestedObjectRef": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/User"
}
}
}
}
},
"definitions": {
"User": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: root_model_with_additional_properties.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from collections.abc import Mapping
from enum import Enum
from pydantic import BaseModel, Field
class NestedObjectResult(BaseModel):
status: int
class NestedEnumResult(Enum):
red = 'red'
green = 'green'
class OneOfResult(BaseModel):
description: str | None = None
class AnyOfResult(BaseModel):
description: str | None = None
class User(BaseModel):
name: str | None = None
class AllOfResult(User):
description: str | None = None
class Model(BaseModel):
test_id: str = Field(..., description='test ID')
test_ip: str = Field(..., description='test IP')
result: Mapping[str, int]
nested_object_result: Mapping[str, NestedObjectResult]
nested_enum_result: Mapping[str, NestedEnumResult]
all_of_result: Mapping[str, AllOfResult] | None = None
one_of_result: Mapping[str, User | OneOfResult] | None = None
any_of_result: Mapping[str, User | AnyOfResult] | None = None
all_of_with_unknown_object: Mapping[str, User] | None = None
objectRef: Mapping[str, User] | None = None
deepNestedObjectRef: Mapping[str, Mapping[str, Mapping[str, User]]] | None = None
--use-non-positive-negative-number-constrained-types¶
Use NonPositive/NonNegative types for number constraints.
The --use-non-positive-negative-number-constrained-types flag generates
Pydantic's NonPositiveInt, NonNegativeInt, NonPositiveFloat, and NonNegativeFloat
types for fields with minimum: 0 or maximum: 0 constraints, instead of using
conint/confloat with ge/le parameters.
Usage
datamodel-codegen --input use_non_positive_negative.json --use-non-positive-negative-number-constrained-types # (1)!
-
--use-non-positive-negative-number-constrained-types- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "NumberConstraints",
"type": "object",
"properties": {
"non_negative_int": {
"type": "integer",
"minimum": 0,
"description": "NonNegativeInt: minimum=0 only"
},
"non_positive_int": {
"type": "integer",
"maximum": 0,
"description": "NonPositiveInt: maximum=0 only"
},
"non_negative_float": {
"type": "number",
"minimum": 0,
"description": "NonNegativeFloat: minimum=0 only"
},
"non_positive_float": {
"type": "number",
"maximum": 0,
"description": "NonPositiveFloat: maximum=0 only"
},
"positive_int": {
"type": "integer",
"exclusiveMinimum": 0,
"description": "PositiveInt: exclusiveMinimum=0"
},
"negative_int": {
"type": "integer",
"exclusiveMaximum": 0,
"description": "NegativeInt: exclusiveMaximum=0"
},
"positive_float": {
"type": "number",
"exclusiveMinimum": 0,
"description": "PositiveFloat: exclusiveMinimum=0"
},
"negative_float": {
"type": "number",
"exclusiveMaximum": 0,
"description": "NegativeFloat: exclusiveMaximum=0"
},
"bounded_non_negative_int": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"description": "NonNegativeInt with additional upper bound"
},
"bounded_non_positive_int": {
"type": "integer",
"maximum": 0,
"minimum": -100,
"description": "NonPositiveInt with additional lower bound"
},
"bounded_non_negative_float": {
"type": "number",
"minimum": 0,
"maximum": 1.0,
"description": "NonNegativeFloat with additional upper bound"
},
"bounded_non_positive_float": {
"type": "number",
"maximum": 0,
"minimum": -1.0,
"description": "NonPositiveFloat with additional lower bound"
},
"plain_constrained_int": {
"type": "integer",
"minimum": 5,
"maximum": 100,
"description": "No zero bound: should remain conint/Field"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: use_non_positive_negative.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import (
BaseModel,
Field,
NegativeFloat,
NegativeInt,
NonNegativeFloat,
NonNegativeInt,
NonPositiveFloat,
NonPositiveInt,
PositiveFloat,
PositiveInt,
confloat,
conint,
)
class NumberConstraints(BaseModel):
non_negative_int: NonNegativeInt | None = Field(
None, description='NonNegativeInt: minimum=0 only'
)
non_positive_int: NonPositiveInt | None = Field(
None, description='NonPositiveInt: maximum=0 only'
)
non_negative_float: NonNegativeFloat | None = Field(
None, description='NonNegativeFloat: minimum=0 only'
)
non_positive_float: NonPositiveFloat | None = Field(
None, description='NonPositiveFloat: maximum=0 only'
)
positive_int: PositiveInt | None = Field(
None, description='PositiveInt: exclusiveMinimum=0'
)
negative_int: NegativeInt | None = Field(
None, description='NegativeInt: exclusiveMaximum=0'
)
positive_float: PositiveFloat | None = Field(
None, description='PositiveFloat: exclusiveMinimum=0'
)
negative_float: NegativeFloat | None = Field(
None, description='NegativeFloat: exclusiveMaximum=0'
)
bounded_non_negative_int: conint(ge=0, le=100) | None = Field(
None, description='NonNegativeInt with additional upper bound'
)
bounded_non_positive_int: conint(ge=-100, le=0) | None = Field(
None, description='NonPositiveInt with additional lower bound'
)
bounded_non_negative_float: confloat(ge=0.0, le=1.0) | None = Field(
None, description='NonNegativeFloat with additional upper bound'
)
bounded_non_positive_float: confloat(ge=-1.0, le=0.0) | None = Field(
None, description='NonPositiveFloat with additional lower bound'
)
plain_constrained_int: conint(ge=5, le=100) | None = Field(
None, description='No zero bound: should remain conint/Field'
)
--use-object-type¶
Use object instead of Any for unspecified object and array values.
The --use-object-type flag configures the code generation to use object
instead of Any when JSON Schema does not define object properties or array
item schemas. This helps generate stricter type hints for unstructured values.
Related: --output-model-type, --target-python-version
Usage
datamodel-codegen --input use_object_type.json --output-model-type typing.TypedDict --target-python-version 3.10 --use-object-type # (1)!
-
--use-object-type- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Payload",
"type": "object",
"properties": {
"metadata": {
"type": "object"
},
"items": {
"type": "array"
},
"nested": {
"type": "array",
"items": {
"type": "object"
}
}
},
"required": ["metadata", "items", "nested"]
}
Output:
--use-pendulum¶
Use pendulum types for date, time, and duration fields.
The --use-pendulum flag maps schema date, time, and duration values to
Pendulum types such as pendulum.Date, pendulum.Time, and pendulum.Duration.
date-time fields continue to use pydantic.AwareDatetime.
If you need a different datetime class for date-time fields, use
--output-datetime-class.
See also: Type Mappings and Custom Types
Usage
-
--use-pendulum- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Event",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"event_date": {
"type": "string",
"format": "date"
},
"duration": {
"type": "string",
"format": "duration"
}
},
"required": ["name", "created_at"]
}
Output:
# generated by datamodel-codegen:
# filename: use_pendulum.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pendulum import Date, Duration
from pydantic import AwareDatetime, BaseModel
class Event(BaseModel):
name: str
created_at: AwareDatetime
event_date: Date | None = None
duration: Duration | None = None
--use-plain-alias-for-recursive-models¶
Write the type alias of a model that names itself as a plain alias in Pydantic output.
A type alias whose whole value is a model that names itself, such as Alias = TypeAliasType("Alias", Node) for
Node.next: Node | None, is refused by Pydantic 2 in the second model that uses it: the module fails to import
(circular-reference-schema), or, where the alias carries metadata, that model fails to validate. With
--use-plain-alias-for-recursive-models the alias is written as Alias: TypeAlias = Node, the model itself, which
every model that uses it builds; it then has no entry of its own in model_json_schema() $defs.
Usage
datamodel-codegen --input recursive_model_alias_two_users.json --output-model-type pydantic_v2.dataclass --use-plain-alias-for-recursive-models # (1)!
-
--use-plain-alias-for-recursive-models- the option documented here
Examples
Input Schema:
{
"$defs": {
"Node": {
"type": "object",
"properties": {
"next": {"$ref": "#/$defs/Node"}
}
},
"Alias": {
"$ref": "#/$defs/Node",
"properties": {
"a": {"type": "string"}
}
},
"Described": {
"$ref": "#/$defs/Node",
"description": "A node beside a description"
},
"Solo": {
"$ref": "#/$defs/Node",
"description": "A node that one class uses"
},
"A": {
"type": "object",
"properties": {
"n": {"$ref": "#/$defs/Alias"},
"d": {"$ref": "#/$defs/Described"},
"s": {"$ref": "#/$defs/Solo"}
}
},
"B": {
"type": "object",
"properties": {
"n": {"$ref": "#/$defs/Alias"},
"d": {"$ref": "#/$defs/Described"}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: recursive_model_alias_two_users.json
from __future__ import annotations
from typing import Annotated, Any, TypeAlias
from pydantic import Field
from pydantic.dataclasses import dataclass
from typing_extensions import TypeAliasType
Model = TypeAliasType("Model", Any)
@dataclass
class Node:
next: Node | None = None
Alias: TypeAlias = Node
Described: TypeAlias = Annotated[
Node, Field(..., description='A node beside a description')
]
Solo: TypeAlias = Annotated[Node, Field(..., description='A node that one class uses')]
@dataclass
class A:
n: Alias | None = None
d: Described | None = None
s: Solo | None = None
@dataclass
class B:
n: Alias | None = None
d: Described | None = None
# generated by datamodel-codegen:
# filename: recursive_model_alias_two_users.json
from __future__ import annotations
from typing import Annotated, Any
from pydantic import Field
from pydantic.dataclasses import dataclass
from typing_extensions import TypeAliasType
Model = TypeAliasType("Model", Any)
@dataclass
class Node:
next: Node | None = None
Alias = TypeAliasType("Alias", Node)
Described = TypeAliasType(
"Described", Annotated[Node, Field(..., description='A node beside a description')]
)
Solo = TypeAliasType(
"Solo", Annotated[Node, Field(..., description='A node that one class uses')]
)
@dataclass
class A:
n: Alias | None = None
d: Described | None = None
s: Solo | None = None
@dataclass
class B:
n: Alias | None = None
d: Described | None = None
--use-root-model-type-alias¶
Generate RootModel as type alias format for better mypy support.
When enabled, root models with simple types are generated as type aliases instead of class definitions, improving mypy type inference.
Usage
datamodel-codegen --input root_model_type_alias.json --use-root-model-type-alias --output-model-type pydantic_v2.BaseModel # (1)!
-
--use-root-model-type-alias- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Pet": {
"type": "object",
"properties": {
"name": {"type": "string"}
}
},
"Pets": {
"oneOf": [
{"$ref": "#/definitions/Pet"},
{"type": "array", "items": {"$ref": "#/definitions/Pet"}}
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: root_model_type_alias.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, RootModel
Model = RootModel[Any]
class Pet(BaseModel):
name: str | None = None
Pets = RootModel[Pet | list[Pet]]
--use-single-dict-for-object-maps¶
Type an object map as one dict instead of a union of dicts.
An object map is an object without properties whose keys patternProperties or propertyNames constrain.
With --use-single-dict-for-object-maps it is one dict whose key pattern joins every pattern and whose value is
the union of their value types, so an object that mixes the keys of several patterns is accepted; a dict that
cannot express the object exactly (keys outside the patterns, different value schemas) is named by a warning.
The null and the other types of a type array, such as [object, string, null], join the dict in a union, and its
property counts stay on the dict; the dict root model of an object without properties, such as a nullable
additionalProperties map, takes the same null. The stricter pattern-map checks of --generate-schema-validators
are under --check-pattern-maps-strictly. Without --use-single-dict-for-object-maps the map is written as in
0.86.0: a union of dicts, one per value type of the patterns, the other types of a type array left out; msgspec,
which cannot decode a union of several dicts, gets the one dict.
Usage
datamodel-codegen --input pattern_properties_merge.json --output-model-type pydantic_v2.BaseModel --use-single-dict-for-object-maps # (1)!
-
--use-single-dict-for-object-maps- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"patternProperties": {
"^i-": {
"type": "string"
},
"^t-": {
"type": "string"
},
"^n-": {
"type": "integer"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: pattern_properties_merge.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import RootModel, constr
class Model(RootModel[dict[constr(pattern=r'^i-|^t-|^n-'), str | int]]):
root: dict[constr(pattern=r'^i-|^t-|^n-'), str | int]
# generated by datamodel-codegen:
# filename: pattern_properties_merge.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import RootModel, constr
class Model(
RootModel[dict[constr(pattern=r'^i-|^t-'), str] | dict[constr(pattern=r'^n-'), int]]
):
root: dict[constr(pattern=r'^i-|^t-'), str] | dict[constr(pattern=r'^n-'), int]
--use-single-value-enum-as-const¶
Treat enum with a single value as const with that value.
JSON Schema defines {"enum": ["low"]} as equal to {"const": "low"}. With
--use-single-value-enum-as-const, each schema in the JSON Schema, OpenAPI and AsyncAPI documents
whose enum lists one value is read as that const, so the output is the same as for the documents
written with const, while the enums that allOf intersections leave stay enums:
oneOf/anyOf branches of single-value enums, as Rust's schemars writes documented unit variants,
become one Enum with branch titles as member names when there are two or more and all hold values
of one JSON type; otherwise each branch is typed as written, such as Literal['a'] | None for one
value beside a null branch or Literal['a'] | Literal[1] for values of different JSON types. A
schema with one enum value is typed Literal[...] instead of a one-member Enum, except one with
nullable: true and a value other than null, which keeps its enum and is read as written. The
option reads const branches the same way, which without it merge into one Enum in those cases
too. Instance data such as default and examples, extension values (x-... except
x-propertyNames), links and servers stay as written, so a schema kept under an extension
key, such as one referenced as headers.yaml#/x-rate, is read as written too. A document parsed
with draft-04 schema features, which have no const, is kept, and Avro, Protocol Buffers, XML
Schema and GraphQL inputs are not changed.
Usage
-
--use-single-value-enum-as-const- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Settings",
"type": "object",
"x-meta": {"enum": ["kept"]},
"properties": {
"level": {"$ref": "#/$defs/Level"},
"phase": {"$ref": "#/$defs/Phase"},
"code": {"$ref": "#/$defs/Code"},
"mode": {"$ref": "#/$defs/Mode"},
"source": {"$ref": "#/$defs/Source"},
"region": {"$ref": "#/$defs/Region"},
"method": {
"type": "string",
"enum": ["settings/update"],
"x-meta": {"enum": ["kept"]}
},
"version": {"type": "integer", "enum": [2], "default": 2},
"default": {"type": "string", "enum": ["named"]},
"both": {"type": "string", "enum": ["same"], "const": "same"},
"options": {
"type": "object",
"additionalProperties": true,
"default": {"enum": ["kept"]},
"examples": [{"enum": ["kept"]}]
},
"pick": {"$ref": "#/$defs/Pick"}
},
"required": ["method"],
"x-generator": {"name": "schemars", "enum": ["kept"]},
"$defs": {
"Level": {
"description": "How much effort to spend.",
"oneOf": [
{"type": "string", "enum": ["low"], "description": "Low effort."},
{"type": "string", "enum": ["high"], "description": "High effort."}
]
},
"Phase": {
"oneOf": [
{"type": "string", "enum": ["commentary"], "title": "Commentary"},
{"type": "string", "enum": ["final_answer"], "title": "FinalAnswer"}
]
},
"Code": {
"oneOf": [
{"type": "integer", "enum": [1], "description": "One."},
{"type": "integer", "enum": [2], "description": "Two."}
]
},
"Mode": {
"anyOf": [{"type": "string", "enum": ["fast"]}, {"type": "string", "enum": ["safe"]}, {"type": "null"}]
},
"Source": {
"oneOf": [
{"type": "string", "enum": ["user"]},
{"type": "string", "const": "agent", "description": "Agent."}
]
},
"Region": {"type": "string", "enum": ["us"]},
"AB": {"type": "string", "enum": ["a", "b"]},
"Pick": {"allOf": [{"$ref": "#/$defs/AB", "enum": ["b", "c"]}]}
}
}
Output:
# generated by datamodel-codegen:
# filename: schema.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum, IntEnum
from typing import Any, Literal
from pydantic import BaseModel, Field, RootModel
class Both(Enum):
same = 'same'
class Level(Enum):
low = 'low'
high = 'high'
class Phase(Enum):
Commentary = 'commentary'
FinalAnswer = 'final_answer'
class Code(IntEnum):
integer_1 = 1
integer_2 = 2
class ModeEnum(Enum):
fast = 'fast'
safe = 'safe'
class Mode(RootModel[ModeEnum | None]):
root: ModeEnum | None = None
class Source(Enum):
user = 'user'
agent = 'agent'
class Region(RootModel[Literal['us']]):
root: Literal['us']
class AB(Enum):
a = 'a'
b = 'b'
class Pick(Enum):
b = 'b'
class Settings(BaseModel):
level: Level | None = None
phase: Phase | None = None
code: Code | None = None
mode: Mode | None = None
source: Source | None = None
region: Region | None = None
method: Literal['settings/update']
version: Literal[2] = 2
default: Literal['named'] | None = None
both: Literal['same'] | None = None
options: dict[str, Any] | None = Field(
{'enum': ['kept']}, examples=[{'enum': ['kept']}]
)
pick: Pick | None = None
# generated by datamodel-codegen:
# filename: schema.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum, IntEnum
from typing import Annotated, Any, Literal, TypeAlias
from msgspec import UNSET, Meta, Struct, UnsetType, field
class Both(Enum):
same = 'same'
class Level(Enum):
low = 'low'
high = 'high'
class Phase(Enum):
Commentary = 'commentary'
FinalAnswer = 'final_answer'
class Code(IntEnum):
integer_1 = 1
integer_2 = 2
class ModeEnum(Enum):
fast = 'fast'
safe = 'safe'
Mode: TypeAlias = ModeEnum | None
class Source(Enum):
user = 'user'
agent = 'agent'
Region: TypeAlias = Literal['us']
class AB(Enum):
a = 'a'
b = 'b'
Pick: TypeAlias = AB
class Settings(Struct):
method: Literal['settings/update']
level: Level | UnsetType = UNSET
phase: Phase | UnsetType = UNSET
code: Code | UnsetType = UNSET
mode: Mode | UnsetType = UNSET
source: Source | UnsetType = UNSET
region: Region | UnsetType = UNSET
version: Literal[2] | UnsetType = 2
default: Literal['named'] | UnsetType = UNSET
both: Both | UnsetType = UNSET
options: (
Annotated[dict[str, Any], Meta(examples=[{'enum': ['kept']}])] | UnsetType
) = field(default_factory=lambda: {'enum': ['kept']})
pick: Pick | UnsetType = UNSET
--use-specialized-enum¶
Generate StrEnum/IntEnum for string/integer enums (Python 3.11+).
The --use-specialized-enum flag generates specialized enum types:
- StrEnum for string enums
- IntEnum for integer enums
This is the default behavior for Python 3.11+ targets.
Related: --no-use-specialized-enum, --use-subclass-enum
Option relationships:
- Requires:
--target-python-version=3.11+---use-specialized-enumrequires--target-python-version3.11 or higher.
Usage
datamodel-codegen --input subclass_enum.json --target-python-version 3.11 --use-specialized-enum # (1)!
-
--use-specialized-enum- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"IntEnum": {
"type": "integer",
"enum": [
1,
2,
3
]
},
"FloatEnum": {
"type": "number",
"enum": [
1.1,
2.1,
3.1
]
},
"StrEnum": {
"type": "string",
"enum": [
"1",
"2",
"3"
]
},
"NonTypedEnum": {
"enum": [
"1",
"2",
"3"
]
},
"BooleanEnum": {
"type": "boolean",
"enum": [
true,
false
]
},
"UnknownEnum": {
"type": "unknown",
"enum": [
"a",
"b"
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: subclass_enum.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum, IntEnum, StrEnum
from pydantic import BaseModel, Field
class IntEnumModel(IntEnum):
integer_1 = 1
integer_2 = 2
integer_3 = 3
class FloatEnum(Enum):
number_1_1 = 1.1
number_2_1 = 2.1
number_3_1 = 3.1
class StrEnumModel(StrEnum):
field_1 = '1'
field_2 = '2'
field_3 = '3'
class NonTypedEnum(Enum):
field_1 = '1'
field_2 = '2'
field_3 = '3'
class BooleanEnum(Enum):
boolean_True = True
boolean_False = False
class UnknownEnum(Enum):
a = 'a'
b = 'b'
class Model(BaseModel):
IntEnum: IntEnumModel | None = None
FloatEnum_1: FloatEnum | None = Field(None, alias='FloatEnum')
StrEnum: StrEnumModel | None = None
NonTypedEnum_1: NonTypedEnum | None = Field(None, alias='NonTypedEnum')
BooleanEnum_1: BooleanEnum | None = Field(None, alias='BooleanEnum')
UnknownEnum_1: UnknownEnum | None = Field(None, alias='UnknownEnum')
--use-standard-collections¶
Use built-in dict/list instead of typing.Dict/List.
The --use-standard-collections flag generates built-in container types
(dict, list) instead of typing module equivalents. This produces cleaner
code for Python 3.10+ where built-in types support subscripting.
Related: --use-generic-container-types
See also: Python Version Compatibility
Usage
datamodel-codegen --input root_model_with_additional_properties.json --use-standard-collections # (1)!
-
--use-standard-collections- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "test.json",
"description": "test",
"type": "object",
"required": [
"test_id",
"test_ip",
"result",
"nested_object_result",
"nested_enum_result"
],
"properties": {
"test_id": {
"type": "string",
"description": "test ID"
},
"test_ip": {
"type": "string",
"description": "test IP"
},
"result": {
"type": "object",
"additionalProperties": {
"type": "integer"
}
},
"nested_object_result": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"status":{
"type": "integer"
}
},
"required": ["status"]
}
},
"nested_enum_result": {
"type": "object",
"additionalProperties": {
"enum": ["red", "green"]
}
},
"all_of_result" :{
"type" : "object",
"additionalProperties" :
{
"allOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"one_of_result" :{
"type" : "object",
"additionalProperties" :
{
"oneOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"any_of_result" :{
"type" : "object",
"additionalProperties" :
{
"anyOf" : [
{ "$ref" : "#/definitions/User" },
{ "type" : "object",
"properties": {
"description": {"type" : "string" }
}
}
]
}
},
"all_of_with_unknown_object" :{
"type" : "object",
"additionalProperties" :
{
"allOf" : [
{ "$ref" : "#/definitions/User" },
{ "description": "TODO" }
]
}
},
"objectRef": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/User"
}
},
"deepNestedObjectRef": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/User"
}
}
}
}
},
"definitions": {
"User": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: root_model_with_additional_properties.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field
class NestedObjectResult(BaseModel):
status: int
class NestedEnumResult(Enum):
red = 'red'
green = 'green'
class OneOfResult(BaseModel):
description: str | None = None
class AnyOfResult(BaseModel):
description: str | None = None
class User(BaseModel):
name: str | None = None
class AllOfResult(User):
description: str | None = None
class Model(BaseModel):
test_id: str = Field(..., description='test ID')
test_ip: str = Field(..., description='test IP')
result: dict[str, int]
nested_object_result: dict[str, NestedObjectResult]
nested_enum_result: dict[str, NestedEnumResult]
all_of_result: dict[str, AllOfResult] | None = None
one_of_result: dict[str, User | OneOfResult] | None = None
any_of_result: dict[str, User | AnyOfResult] | None = None
all_of_with_unknown_object: dict[str, User] | None = None
objectRef: dict[str, User] | None = None
deepNestedObjectRef: dict[str, dict[str, dict[str, User]]] | None = None
--use-standard-primitive-types¶
Use Python standard library types for string formats instead of str.
The --use-standard-primitive-types flag configures the code generation to use
Python standard library types (UUID, IPv4Address, IPv6Address, Path) for corresponding
string formats instead of plain str. This affects dataclass, msgspec, and TypedDict
output types. Pydantic already uses these types by default.
Related: --output-datetime-class, --output-model-type
Usage
datamodel-codegen --input use_standard_primitive_types.json --output-model-type dataclasses.dataclass --use-standard-primitive-types # (1)!
-
--use-standard-primitive-types- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"ip_address": {
"type": "string",
"format": "ipv4"
},
"config_path": {
"type": "string",
"format": "path"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: use_standard_primitive_types.json
from __future__ import annotations
from dataclasses import dataclass
from ipaddress import IPv4Address
from pathlib import Path
from uuid import UUID
@dataclass
class Model:
id: UUID | None = None
ip_address: IPv4Address | None = None
config_path: Path | None = None
--use-strict-str-for-base64¶
Make a format: byte string strict under --strict-types str.
--strict-types str writes a string as StrictStr, which refuses bytes, but leaves a format: byte string
Base64Str, or the str that --use-encoded-str-for-constrained-base64 writes, which accept bytes:
Model(b=b"aGk=") gives 'hi'. With this option the string is the StrictStr that EncodedStr decodes,
Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)], with the constraints the field form writes in front of the
decoding, at a property, an item, a map value, a root, a union member and a collapsed root, so Pydantic 2.10 or later
refuses bytes for it as for any other strict string, while JSON input validates as before. Pydantic before 2.10
accepts bytes for it, and a target Pydantic older than 2.10 warns so. Without --strict-types str the option
changes nothing.
Usage
datamodel-codegen --input encoded_str_for_constrained_base64.json --strict-types str --use-strict-str-for-base64 # (1)!
-
--use-strict-str-for-base64- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "EncodedStrForConstrainedBase64",
"type": "object",
"required": ["required"],
"properties": {
"pattern": {"type": "string", "format": "byte", "pattern": "^Y"},
"lengths": {"type": "string", "format": "byte", "minLength": 4, "maxLength": 8},
"required": {"type": "string", "format": "byte", "minLength": 4},
"nullable": {"type": ["string", "null"], "format": "byte", "maxLength": 8},
"plain": {"type": "string", "format": "byte"},
"items": {"type": "array", "items": {"type": "string", "format": "byte", "maxLength": 8}},
"values": {"type": "object", "additionalProperties": {"type": "string", "format": "byte", "pattern": "^Y"}},
"ref": {"$ref": "#/$defs/Short"},
"member": {"anyOf": [{"type": "string", "format": "byte", "maxLength": 8}, {"type": "integer"}]},
"branch": {"type": ["array", "string"], "format": "byte", "maxLength": 8, "items": {"type": "integer"}}
},
"$defs": {
"Short": {"type": "string", "format": "byte", "maxLength": 8}
}
}
Output:
# generated by datamodel-codegen:
# filename: encoded_str_for_constrained_base64.json
from __future__ import annotations
from typing import Annotated
from pydantic import Base64Encoder, BaseModel, EncodedStr, Field, RootModel, StrictStr
from typing_extensions import TypeAliasType
BranchString = TypeAliasType(
"BranchString",
Annotated[
Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)], Field(max_length=8)
],
)
class Short(RootModel[Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)]]):
root: Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)]
class EncodedStrForConstrainedBase64(BaseModel):
pattern: Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)] | None = None
lengths: Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)] | None = None
required: Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)]
nullable: Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)] | None = None
plain: Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)] | None = None
items: list[Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)]] | None = None
values: (
dict[str, Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)]] | None
) = None
ref: Short | None = None
member: Annotated[StrictStr, EncodedStr(encoder=Base64Encoder)] | int | None = None
branch: BranchString | list[int] | None = None
Error: File not found: main/jsonschema/encoded_str_for_constrained_base64~main_encoded_str_for_constrained_base64[strict_released].py
--use-total-false-for-typed-dict¶
Generate TypedDict declarations with total=False.
Optional fields are left unwrapped, while required fields are marked with
Required[...]. This can substantially reduce generated code when most fields
are optional.
Usage
datamodel-codegen --input use_total_false_for_typed_dict.json --output-model-type typing.TypedDict --use-total-false-for-typed-dict --use-frozen-field # (1)!
-
--use-total-false-for-typed-dict- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"ClassModel": {
"type": "object",
"properties": {
"required_value": {
"type": "string"
},
"optional_value": {
"type": "integer"
},
"required_read_only": {
"type": "boolean",
"readOnly": true
},
"optional_read_only": {
"type": "number",
"readOnly": true
}
},
"required": [
"required_value",
"required_read_only"
]
},
"BaseModel": {
"type": "object",
"properties": {
"base_required": {
"type": "string"
},
"base_optional": {
"type": "integer"
}
},
"required": [
"base_required"
]
},
"FunctionalModel": {
"allOf": [
{
"$ref": "#/$defs/BaseModel"
},
{
"type": "object",
"properties": {
"invalid-key": {
"type": "string"
},
"child_optional": {
"type": "boolean"
}
},
"required": [
"invalid-key"
]
}
]
},
"ClosedModel": {
"type": "object",
"additionalProperties": false,
"properties": {
"closed_required": {
"type": "string"
},
"closed_optional": {
"type": "integer"
}
},
"required": [
"closed_required"
]
},
"ExtraItemsModel": {
"type": "object",
"additionalProperties": {
"type": "integer"
},
"properties": {
"extra_required": {
"type": "string"
},
"extra_optional": {
"type": "boolean"
}
},
"required": [
"extra_required"
]
}
},
"type": "object",
"properties": {
"class_model": {
"$ref": "#/$defs/ClassModel"
},
"functional_model": {
"$ref": "#/$defs/FunctionalModel"
},
"closed_model": {
"$ref": "#/$defs/ClosedModel"
},
"extra_items_model": {
"$ref": "#/$defs/ExtraItemsModel"
}
},
"required": [
"class_model"
]
}
Output:
# generated by datamodel-codegen:
# filename: use_total_false_for_typed_dict.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing_extensions import ReadOnly, Required, TypedDict
class ClassModel(TypedDict, total=False):
required_value: Required[str]
optional_value: int
required_read_only: Required[ReadOnly[bool]]
optional_read_only: ReadOnly[float]
class BaseModel(TypedDict, total=False):
base_required: Required[str]
base_optional: int
FunctionalModel = TypedDict(
'FunctionalModel',
{
'base_required': Required[str],
'base_optional': int,
'invalid-key': Required[str],
'child_optional': bool,
},
total=False,
)
class ClosedModel(TypedDict, total=False, closed=True):
closed_required: Required[str]
closed_optional: int
class ExtraItemsModel(TypedDict, total=False, extra_items=int):
extra_required: Required[str]
extra_optional: bool
class Model(TypedDict, total=False):
class_model: Required[ClassModel]
functional_model: FunctionalModel
closed_model: ClosedModel
extra_items_model: ExtraItemsModel
# generated by datamodel-codegen:
# filename: use_total_false_for_typed_dict.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Required
from typing_extensions import ReadOnly, TypedDict
class ClassModel(TypedDict, total=False):
required_value: Required[str]
optional_value: int
required_read_only: Required[ReadOnly[bool]]
optional_read_only: ReadOnly[float]
class BaseModel(TypedDict, total=False):
base_required: Required[str]
base_optional: int
FunctionalModel = TypedDict(
'FunctionalModel',
{
'base_required': Required[str],
'base_optional': int,
'invalid-key': Required[str],
'child_optional': bool,
},
total=False,
)
class ClosedModel(TypedDict, total=False, closed=True):
closed_required: Required[str]
closed_optional: int
class ExtraItemsModel(TypedDict, total=False, extra_items=int):
extra_required: Required[str]
extra_optional: bool
class Model(TypedDict, total=False):
class_model: Required[ClassModel]
functional_model: FunctionalModel
closed_model: ClosedModel
extra_items_model: ExtraItemsModel
--use-tuple-for-closed-arrays¶
Generate tuple types for positional arrays that no other item can follow.
A prefixItems array whose tail is closed by items: false, unevaluatedItems: false, a false position or
contains, and an items array closed by additionalItems: false or a false position, is written as a tuple
when its length bounds fix its length, so every position keeps its own type. Without the option only equal
minItems and maxItems make a tuple, and a closed array is a list with length constraints that accepts items in
the wrong positions. When bounds other than equal minItems and maxItems fix the length, the list stays if its
item schemas (the allowed positions and the items schema) accept the same values, compared without annotations
and x- keys, with a $ref read as its target and type: [T] as type: T. --use-tuple-for-fixed-items still
decides whether the items array form is read. A tuple cannot hold uniqueItems: with --use-unique-items-as-set
it stays a tuple and a warning names the field generated without uniqueness, unless --generate-schema-validators
checks it.
Usage
-
--use-tuple-for-closed-arrays- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "PrefixItemsClosedLength",
"type": "object",
"properties": {
"closed_by_items_false": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "integer"}],
"items": false,
"minItems": 2
},
"closed_by_unevaluated_items_false": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "integer"}],
"unevaluatedItems": false,
"minItems": 2
},
"closed_by_false_position": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "integer"}, false],
"minItems": 2
},
"closed_below_max_items": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "integer"}],
"items": false,
"minItems": 2,
"maxItems": 5
},
"closed_nullable": {
"type": ["array", "null"],
"prefixItems": [{"type": "string"}, {"type": "integer"}],
"items": false,
"minItems": 2
},
"closed_by_contains": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "integer"}],
"contains": true,
"minContains": 2,
"maxContains": 2
},
"closed_by_contains_beyond_positions": {
"type": "array",
"prefixItems": [{"type": "string"}],
"contains": {},
"minContains": 3,
"maxContains": 3
},
"closed_to_one_position": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "integer"}],
"contains": {},
"maxContains": 1
},
"closed_before_other_positions": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "string"}, {"type": "integer"}],
"items": false,
"maxItems": 2,
"contains": {},
"minContains": 2
},
"kept_one_schema": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "string"}],
"items": false,
"minItems": 2
},
"kept_one_schema_apart_from_annotations": {
"type": "array",
"prefixItems": [{"type": "string", "description": "first", "$comment": "first position"}, {"type": "string"}],
"items": false,
"minItems": 2
},
"kept_one_position": {
"type": "array",
"prefixItems": [{"type": "string"}],
"items": false,
"minItems": 1
},
"kept_one_schema_with_tail": {
"type": "array",
"prefixItems": [{"type": "string", "x-position": "first"}],
"items": {"type": "string", "x-position": "first"},
"contains": {},
"minContains": 3,
"maxContains": 3
},
"kept_variable_length": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "integer"}],
"items": false,
"minItems": 1
},
"closed_by_type_list": {
"type": "array",
"prefixItems": [{"type": ["string", "null"]}, {"type": "string"}],
"items": false,
"minItems": 2
},
"kept_apart_from_extension_keys": {
"type": "array",
"prefixItems": [{"type": "string", "x-order": 1}, {"type": "string"}],
"items": false,
"minItems": 2
},
"kept_ref_and_equal_inline": {
"type": "array",
"prefixItems": [{"$ref": "#/$defs/Name"}, {"type": "string", "maxLength": 5}],
"items": false,
"minItems": 2
},
"kept_type_list_of_one": {
"type": "array",
"prefixItems": [{"type": ["string"]}, {"type": "string"}],
"items": false,
"minItems": 2
},
"kept_ref_to_root_with_extension_key": {
"type": "array",
"prefixItems": [{"$ref": "#/$defs/Tagged"}, {"type": "integer"}],
"items": false,
"minItems": 2
},
"kept_nested_items": {
"type": "array",
"prefixItems": [
{"type": "array", "items": {"type": "string", "title": "Tag"}},
{"type": "array", "items": {"type": "string"}}
],
"items": false,
"minItems": 2
},
"kept_nested_any_of": {
"type": "array",
"prefixItems": [
{"anyOf": [{"type": "string"}, {"type": "integer", "description": "A count."}]},
{"anyOf": [{"type": "string"}, {"type": "integer"}]}
],
"items": false,
"minItems": 2
},
"kept_nested_dependent_schemas": {
"type": "array",
"prefixItems": [
{"type": "object", "dependentSchemas": {"a": {"type": "object", "required": ["b"], "description": "Needs b."}}},
{"type": "object", "dependentSchemas": {"a": {"type": "object", "required": ["b"]}}}
],
"items": false,
"minItems": 2
},
"explicit_one_schema": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "string"}],
"minItems": 2,
"maxItems": 2
},
"inherited": {"$ref": "#/$defs/Child"}
},
"$defs": {
"Name": {"type": "string", "maxLength": 5, "description": "A name."},
"Tagged": {"type": "integer", "x-kind": "tag"},
"Parent": {
"type": "object",
"properties": {
"closed": {
"type": "array",
"prefixItems": [{"type": "string"}, {"type": "integer"}],
"items": false,
"minItems": 2
}
}
},
"Child": {
"allOf": [
{"$ref": "#/$defs/Parent"},
{"type": "object", "properties": {"closed": {"type": "array", "prefixItems": [{"type": "string", "maxLength": 3}]}}}
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: prefix_items_closed_length.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field, RootModel, constr
class KeptRefAndEqualInlineItem(RootModel[constr(max_length=5)]):
root: constr(max_length=5)
class Name(RootModel[constr(max_length=5)]):
root: constr(max_length=5) = Field(..., description='A name.')
class Tagged(RootModel[int]):
root: int
class Parent(BaseModel):
closed: tuple[str, int] | None = None
class ClosedItem(RootModel[constr(max_length=3)]):
root: constr(max_length=3)
class Child(Parent):
closed: tuple[ClosedItem, int] | None = None
class PrefixItemsClosedLength(BaseModel):
closed_by_items_false: tuple[str, int] | None = None
closed_by_unevaluated_items_false: tuple[str, int] | None = None
closed_by_false_position: tuple[str, int] | None = None
closed_below_max_items: tuple[str, int] | None = None
closed_nullable: tuple[str, int] | None = None
closed_by_contains: tuple[str, int] | None = None
closed_by_contains_beyond_positions: tuple[str, Any, Any] | None = None
closed_to_one_position: tuple[str] | None = None
closed_before_other_positions: tuple[str, str] | None = None
kept_one_schema: list[str] | None = Field(None, max_length=2, min_length=2)
kept_one_schema_apart_from_annotations: list[str] | None = Field(
None, max_length=2, min_length=2
)
kept_one_position: list[str] | None = Field(None, max_length=1, min_length=1)
kept_one_schema_with_tail: list[str] | None = Field(
None, max_length=3, min_length=3
)
kept_variable_length: list[str | int] | None = Field(
None, max_length=2, min_length=1
)
closed_by_type_list: tuple[str | None, str] | None = None
kept_apart_from_extension_keys: list[str] | None = Field(
None, max_length=2, min_length=2
)
kept_ref_and_equal_inline: list[Name | KeptRefAndEqualInlineItem] | None = Field(
None, max_length=2, min_length=2
)
kept_type_list_of_one: list[str] | None = Field(None, max_length=2, min_length=2)
kept_ref_to_root_with_extension_key: list[Tagged | int] | None = Field(
None, max_length=2, min_length=2
)
kept_nested_items: list[list[str]] | None = Field(None, max_length=2, min_length=2)
kept_nested_any_of: list[str | int] | None = Field(None, max_length=2, min_length=2)
kept_nested_dependent_schemas: list[dict[str, Any]] | None = Field(
None, max_length=2, min_length=2
)
explicit_one_schema: tuple[str, str] | None = None
inherited: Child | None = None
# generated by datamodel-codegen:
# filename: prefix_items_closed_length.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field, RootModel, constr
class KeptRefAndEqualInlineItem(RootModel[constr(max_length=5)]):
root: constr(max_length=5)
class Name(RootModel[constr(max_length=5)]):
root: constr(max_length=5) = Field(..., description='A name.')
class Tagged(RootModel[int]):
root: int
class Parent(BaseModel):
closed: list[str | int] | None = Field(None, max_length=2, min_length=2)
class ClosedItem(RootModel[constr(max_length=3)]):
root: constr(max_length=3)
class Child(Parent):
closed: list[ClosedItem | int] | None = Field(None, max_length=2, min_length=2)
class PrefixItemsClosedLength(BaseModel):
closed_by_items_false: list[str | int] | None = Field(
None, max_length=2, min_length=2
)
closed_by_unevaluated_items_false: list[str | int] | None = Field(
None, max_length=2, min_length=2
)
closed_by_false_position: list[str | int] | None = Field(
None, max_length=2, min_length=2
)
closed_below_max_items: list[str | int] | None = Field(
None, max_length=2, min_length=2
)
closed_nullable: list[str | int] | None = Field(None, max_length=2, min_length=2)
closed_by_contains: list[Any] | None = Field(None, max_length=2, min_length=2)
closed_by_contains_beyond_positions: list[Any] | None = Field(
None, max_length=3, min_length=3
)
closed_to_one_position: list[Any] | None = Field(None, max_length=1, min_length=1)
closed_before_other_positions: list[str | int] | None = Field(
None, max_length=2, min_length=2
)
kept_one_schema: list[str] | None = Field(None, max_length=2, min_length=2)
kept_one_schema_apart_from_annotations: list[str] | None = Field(
None, max_length=2, min_length=2
)
kept_one_position: list[str] | None = Field(None, max_length=1, min_length=1)
kept_one_schema_with_tail: list[str] | None = Field(
None, max_length=3, min_length=3
)
kept_variable_length: list[str | int] | None = Field(
None, max_length=2, min_length=1
)
closed_by_type_list: list[str | None] | None = Field(
None, max_length=2, min_length=2
)
kept_apart_from_extension_keys: list[str] | None = Field(
None, max_length=2, min_length=2
)
kept_ref_and_equal_inline: list[Name | KeptRefAndEqualInlineItem] | None = Field(
None, max_length=2, min_length=2
)
kept_type_list_of_one: list[str] | None = Field(None, max_length=2, min_length=2)
kept_ref_to_root_with_extension_key: list[Tagged | int] | None = Field(
None, max_length=2, min_length=2
)
kept_nested_items: list[list[str]] | None = Field(None, max_length=2, min_length=2)
kept_nested_any_of: list[str | int] | None = Field(None, max_length=2, min_length=2)
kept_nested_dependent_schemas: list[dict[str, Any]] | None = Field(
None, max_length=2, min_length=2
)
explicit_one_schema: tuple[str, str] | None = None
inherited: Child | None = None
--use-tuple-for-fixed-items¶
Generate tuple types for arrays with items array syntax.
When --use-tuple-for-fixed-items is enabled and an array has items as an array
with minItems == maxItems == len(items), generate a tuple type instead of a list.
Usage
-
--use-tuple-for-fixed-items- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"point": {
"type": "array",
"items": [{"type": "number"}, {"type": "number"}],
"minItems": 2,
"maxItems": 2
}
},
"required": ["point"]
}
Output:
--use-tuple-for-fixed-length-arrays¶
Generate tuple types for homogeneous fixed-length arrays.
When --use-tuple-for-fixed-length-arrays is enabled and an array has one
items schema with minItems == maxItems, generate a tuple type instead of a
list. An empty fixed-length array becomes tuple[()].
Usage
datamodel-codegen --input fixed_length_array_tuples.yaml --use-tuple-for-fixed-length-arrays --output-model-type pydantic_v2.BaseModel # (1)!
-
--use-tuple-for-fixed-length-arrays- the option documented here
Examples
Input Schema:
openapi: 3.0.3
info:
title: Fixed length array tuples
version: 1.0.0
paths: {}
components:
schemas:
FixedLengthArrayTuples:
type: object
required:
- vector
- allOfVector
- allOfEmpty
- empty
- inlineObject
- refValues
- range
- minimumOnly
properties:
vector:
type: array
minItems: 3
maxItems: 3
items:
type: number
format: double
allOfVector:
allOf:
- type: array
minItems: 2
maxItems: 2
items:
type: string
allOfEmpty:
allOf:
- type: array
minItems: 0
maxItems: 0
items:
type: string
empty:
type: array
minItems: 0
maxItems: 0
items:
type: number
format: double
inlineObject:
type: array
minItems: 2
maxItems: 2
items:
type: object
required:
- value
properties:
value:
type: string
refValues:
type: array
minItems: 3
maxItems: 3
items:
$ref: '#/components/schemas/RefValue'
range:
type: array
minItems: 2
maxItems: 4
items:
type: integer
minimumOnly:
type: array
minItems: 3
items:
type: string
RefValue:
type: object
required:
- id
properties:
id:
type: integer
Output:
# generated by datamodel-codegen:
# filename: fixed_length_array_tuples.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field, RootModel
class AllOfVector(RootModel[tuple[str, str]]):
root: tuple[str, str]
class AllOfEmpty(RootModel[tuple[()]]):
root: tuple[()]
class InlineObjectItem(BaseModel):
value: str
class RefValue(BaseModel):
id: int
class FixedLengthArrayTuples(BaseModel):
vector: tuple[float, float, float]
allOfVector: AllOfVector
allOfEmpty: AllOfEmpty
empty: tuple[()]
inlineObject: tuple[InlineObjectItem, InlineObjectItem]
refValues: tuple[RefValue, RefValue, RefValue]
range: list[int] = Field(..., max_length=4, min_length=2)
minimumOnly: list[str] = Field(..., min_length=3)
--use-type-alias¶
Use TypeAlias instead of root models for type definitions (experimental).
The --use-type-alias flag generates TypeAlias declarations instead of
root model classes for certain type definitions. For Python 3.10-3.11, it
generates TypeAliasType, and for Python 3.12+, it uses the 'type' statement
syntax. This feature is experimental.
Related: --target-python-version
See also: Model Reuse and Deduplication, Root Models and Type Aliases
Usage
-
--use-type-alias- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"SimpleString": {
"type": "string"
},
"UnionType": {
"anyOf": [
{"type": "string"},
{"type": "integer"}
]
},
"ArrayType": {
"type": "array",
"items": {"type": "string"}
},
"AnnotatedType": {
"title": "MyAnnotatedType",
"description": "An annotated union type",
"anyOf": [
{"type": "string"},
{"type": "boolean"}
]
},
"ModelWithTypeAliasField": {
"type": "object",
"properties": {
"simple_field": {"$ref": "#/definitions/SimpleString"},
"union_field": {"$ref": "#/definitions/UnionType"},
"array_field": {"$ref": "#/definitions/ArrayType"},
"annotated_field": {"$ref": "#/definitions/AnnotatedType"}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: type_alias.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Annotated, Any
from pydantic import BaseModel, Field
from typing_extensions import TypeAliasType
Model = TypeAliasType("Model", Any)
SimpleString = TypeAliasType("SimpleString", str)
UnionType = TypeAliasType("UnionType", str | int)
ArrayType = TypeAliasType("ArrayType", list[str])
AnnotatedType = TypeAliasType(
"AnnotatedType",
Annotated[
str | bool,
Field(..., description='An annotated union type', title='MyAnnotatedType'),
],
)
class ModelWithTypeAliasField(BaseModel):
simple_field: SimpleString | None = None
union_field: UnionType | None = None
array_field: ArrayType | None = None
annotated_field: AnnotatedType | None = None
Input Schema:
scalar SimpleString
type Person {
name: String!
age: Int!
}
type Pet {
name: String!
type: String!
}
union UnionType = Person | Pet
type ModelWithTypeAliasField {
simple_field: SimpleString
union_field: UnionType
string_field: String
}
Output:
# generated by datamodel-codegen:
# filename: type_alias.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Literal, Union
from pydantic import BaseModel, Field
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
Int = TypeAliasType("Int", int)
"""
The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
"""
SimpleString = TypeAliasType("SimpleString", str)
String = TypeAliasType("String", str)
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class Person(BaseModel):
age: Int
name: String
typename__: Literal['Person'] | None = Field('Person', alias='__typename')
class Pet(BaseModel):
name: String
type: String
typename__: Literal['Pet'] | None = Field('Pet', alias='__typename')
UnionType = TypeAliasType(
"UnionType",
Union[
'Person',
'Pet',
],
)
class ModelWithTypeAliasField(BaseModel):
simple_field: SimpleString | None = None
string_field: String | None = None
union_field: UnionType | None = None
typename__: Literal['ModelWithTypeAliasField'] | None = Field(
'ModelWithTypeAliasField', alias='__typename'
)
--use-type-alias-type¶
Use runtime TypeAliasType objects for aliases before Python 3.12 (experimental).
The --use-type-alias-type flag implies --use-type-alias and forces
TypeAliasType for every output model type on Python 3.10-3.11. Python 3.12+
continues to use native type statements.
See also: Root Models and Type Aliases
Option relationships:
- Implies:
--use-type-aliasenabled
Usage
datamodel-codegen --input type_alias.json --output-model-type typing.TypedDict --use-type-alias-type --target-python-version 3.10 # (1)!
-
--use-type-alias-type- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"SimpleString": {
"type": "string"
},
"UnionType": {
"anyOf": [
{"type": "string"},
{"type": "integer"}
]
},
"ArrayType": {
"type": "array",
"items": {"type": "string"}
},
"AnnotatedType": {
"title": "MyAnnotatedType",
"description": "An annotated union type",
"anyOf": [
{"type": "string"},
{"type": "boolean"}
]
},
"ModelWithTypeAliasField": {
"type": "object",
"properties": {
"simple_field": {"$ref": "#/definitions/SimpleString"},
"union_field": {"$ref": "#/definitions/UnionType"},
"array_field": {"$ref": "#/definitions/ArrayType"},
"annotated_field": {"$ref": "#/definitions/AnnotatedType"}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: type_alias.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any, TypedDict
from typing_extensions import NotRequired, TypeAliasType
Model = TypeAliasType("Model", Any)
SimpleString = TypeAliasType("SimpleString", str)
UnionType = TypeAliasType("UnionType", str | int)
ArrayType = TypeAliasType("ArrayType", list[str])
AnnotatedType = TypeAliasType("AnnotatedType", str | bool)
class ModelWithTypeAliasField(TypedDict):
simple_field: NotRequired[SimpleString]
union_field: NotRequired[UnionType]
array_field: NotRequired[ArrayType]
annotated_field: NotRequired[AnnotatedType]
# generated by datamodel-codegen:
# filename: type_alias.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any, NotRequired, TypedDict
type Model = Any
type SimpleString = str
type UnionType = str | int
type ArrayType = list[str]
type AnnotatedType = str | bool
class ModelWithTypeAliasField(TypedDict):
simple_field: NotRequired[SimpleString]
union_field: NotRequired[UnionType]
array_field: NotRequired[ArrayType]
annotated_field: NotRequired[AnnotatedType]
--use-typed-map-values-beside-other-types¶
Type the map values of type arrays that list object beside other types.
With --use-typed-nullable-map-values, a schema whose type array lists object beside other types, such as
type: [object, string] or type: [object, string, "null"], and that declares its values with
additionalProperties gets typed values too, such as dict[str, int] | str, with a model for object values.
Without this option those maps keep dict[str, Any], as in 0.86.0, while the maps whose type array lists object
alone or with null are typed by --use-typed-nullable-map-values either way. The option changes nothing without
--use-typed-nullable-map-values.
Usage
datamodel-codegen --input typed_map_values_beside_other_types.json --output-model-type pydantic_v2.BaseModel --use-typed-nullable-map-values --use-typed-map-values-beside-other-types # (1)!
-
--use-typed-map-values-beside-other-types- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Settings",
"type": "object",
"properties": {
"limits": {
"type": ["object", "null"],
"additionalProperties": {"type": "integer"}
},
"quotas": {
"type": ["object", "string"],
"additionalProperties": {"type": "integer"}
},
"owners": {
"type": ["object", "string", "null"],
"additionalProperties": {
"type": "object",
"properties": {"name": {"type": "string"}}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: typed_map_values_beside_other_types.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel
class Owners(BaseModel):
name: str | None = None
class Settings(BaseModel):
limits: dict[str, int] | None = None
quotas: dict[str, int] | str | None = None
owners: dict[str, Owners] | str | None = None
# generated by datamodel-codegen:
# filename: typed_map_values_beside_other_types.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel
class Settings(BaseModel):
limits: dict[str, int] | None = None
quotas: dict[str, Any] | str | None = None
owners: dict[str, Any] | str | None = None
--use-typed-nullable-map-values¶
Type the values of nullable maps as their schemas say instead of Any.
A nullable map here is a schema whose type array lists object alone or with null, such as
type: [object, "null"] or type: [object], and that declares its values with additionalProperties. Without the
--use-typed-nullable-map-values flag the output keeps the 0.83.0 form, dict[str, Any] | None, or
dict[str, Any] when the type array has no null, whatever the values are. A map made nullable by nullable: true
and a map typed type: object keep their typed values either way. The maps of type arrays that list object
beside other types, such as type: [object, string], are typed only with
--use-typed-map-values-beside-other-types too.
With the flag the values follow their schema, such as dict[str, int] | None or dict[str, Player] | None, and an
object value gets a model named after the map, such as Teams1 for the values of Teams. Those value models take
the names left free, so the other models keep their 0.83.0 names, and options keyed by class name, such as
--base-class-map or --aliases, apply to the final names. Typed values change more than the maps themselves:
--reuse-model makes a value model and the models equal to it one model, which can leave out a schema's class, and
no longer makes nullable maps with different values subclasses of each other, and --collapse-root-models collapses
the root models that the values use. When typing the values would change the modules written, the values of the
whole run stay untyped.
Usage
datamodel-codegen --input nullable_map_value_types.yaml --use-typed-nullable-map-values --output-model-type pydantic_v2.BaseModel # (1)!
-
--use-typed-nullable-map-values- the option documented here
Examples
Input Schema:
openapi: 3.1.0
info:
title: Nullable map value types
version: "1.0"
paths:
/scores:
get:
operationId: listScores
parameters:
- name: players
in: query
schema:
type: [object, "null"]
additionalProperties:
$ref: "#/components/schemas/Player"
responses:
"200":
description: The scores.
post:
operationId: replaceScores
requestBody:
content:
application/json:
schema:
type: [object, "null"]
additionalProperties:
type: integer
responses:
"200":
description: The stored scores.
content:
application/json:
schema:
$ref: "#/components/schemas/Scores"
components:
schemas:
Player:
type: object
properties:
name:
type: string
Scores:
type: [object, "null"]
additionalProperties:
type: integer
NullFirstScores:
type: ["null", object]
additionalProperties:
type: integer
ObjectOnlyScores:
type: [object]
additionalProperties:
type: integer
Players:
type: [object, "null"]
additionalProperties:
$ref: "#/components/schemas/Player"
Teams:
type: [object, "null"]
additionalProperties:
type: object
properties:
captain:
$ref: "#/components/schemas/Player"
Rounds:
type: [object, "null"]
additionalProperties:
type: array
items:
type: integer
Seasons:
type: [object, "null"]
additionalProperties:
type: [object, "null"]
additionalProperties:
type: number
Labels:
type: [object, "null"]
additionalProperties:
type: string
minLength: 1
Board:
type: object
required:
- scores
properties:
scores:
type: [object, "null"]
additionalProperties:
type: integer
players:
type: [object, "null"]
additionalProperties:
$ref: "#/components/schemas/Player"
teams:
type: [object, "null"]
additionalProperties:
type: object
properties:
captain:
$ref: "#/components/schemas/Player"
history:
type: array
items:
type: [object, "null"]
additionalProperties:
type: integer
plain:
type: object
additionalProperties:
type: integer
nullable_array:
type: [array, "null"]
items:
type: integer
untyped:
type: [object, "null"]
additionalProperties: true
fixed:
type: [object, "null"]
additionalProperties:
type: integer
const:
x: 1
Output:
# generated by datamodel-codegen:
# filename: nullable_map_value_types.yaml
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, RootModel, constr
class Player(BaseModel):
name: str | None = None
class Scores(RootModel[dict[str, int] | None]):
root: dict[str, int] | None
class NullFirstScores(RootModel[dict[str, int] | None]):
root: dict[str, int] | None
class ObjectOnlyScores(RootModel[dict[str, int]]):
root: dict[str, int]
class Players(RootModel[dict[str, Player] | None]):
root: dict[str, Player] | None
class Teams1(BaseModel):
captain: Player | None = None
class Teams(RootModel[dict[str, Teams1] | None]):
root: dict[str, Teams1] | None
class Rounds(RootModel[dict[str, list[int]] | None]):
root: dict[str, list[int]] | None
class Seasons(RootModel[dict[str, dict[str, float] | None] | None]):
root: dict[str, dict[str, float] | None] | None
class Labels(RootModel[dict[str, constr(min_length=1)] | None]):
root: dict[str, constr(min_length=1)] | None
class Teams2(BaseModel):
captain: Player | None = None
class Board(BaseModel):
scores: dict[str, int] | None
players: dict[str, Player] | None = None
teams: dict[str, Teams2] | None = None
history: list[dict[str, int] | None] | None = None
plain: dict[str, int] | None = None
nullable_array: list[int] | None = None
untyped: dict[str, Any] | None = None
fixed: dict[str, int] = None
# generated by datamodel-codegen:
# filename: nullable_map_value_types.yaml
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, RootModel
class Player(BaseModel):
name: str | None = None
class Scores(RootModel[dict[str, Any] | None]):
root: dict[str, Any] | None
class NullFirstScores(RootModel[dict[str, Any] | None]):
root: dict[str, Any] | None
class ObjectOnlyScores(RootModel[dict[str, Any]]):
root: dict[str, Any]
class Players(RootModel[dict[str, Any] | None]):
root: dict[str, Any] | None
class Teams(RootModel[dict[str, Any] | None]):
root: dict[str, Any] | None
class Rounds(RootModel[dict[str, Any] | None]):
root: dict[str, Any] | None
class Seasons(RootModel[dict[str, Any] | None]):
root: dict[str, Any] | None
class Labels(RootModel[dict[str, Any] | None]):
root: dict[str, Any] | None
class Board(BaseModel):
scores: dict[str, Any] | None
players: dict[str, Any] | None = None
teams: dict[str, Any] | None = None
history: list[dict[str, Any] | None] | None = None
plain: dict[str, int] | None = None
nullable_array: list[int] | None = None
untyped: dict[str, Any] | None = None
fixed: dict[str, int] = None
--use-union-operator¶
Use | operator for Union types (PEP 604).
The --use-union-operator flag generates union types using the | operator
(e.g., str | None) instead of Union[str, None] or Optional[str].
This is the default behavior.
Related: --no-use-union-operator
See also: Python Version Compatibility
Usage
datamodel-codegen --input annotated.graphql --output-model-type pydantic_v2.BaseModel --use-annotated --use-union-operator # (1)!
-
--use-union-operator- the option documented here
Examples
Input Schema:
type A {
field: String!
optionalField: String
listField: [String!]!
listOptionalField: [String]!
optionalListField: [String!]
optionalListOptionalField: [String]
listListField:[[String!]!]!
}
Output:
# generated by datamodel-codegen:
# filename: annotated.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Annotated, Literal
from pydantic import BaseModel, Field
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
String = TypeAliasType("String", str)
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class A(BaseModel):
field: String
listField: list[String]
listListField: list[list[String]]
listOptionalField: list[String | None]
optionalField: String | None = None
optionalListField: list[String] | None = None
optionalListOptionalField: list[String | None] | None = None
typename__: Annotated[Literal['A'] | None, Field(alias='__typename')] = 'A'
--use-unique-items-as-set¶
Generate set types for arrays with uniqueItems constraint.
The --use-unique-items-as-set flag generates Python set types instead of
list types for JSON Schema arrays that have the uniqueItems constraint set
to true, enforcing uniqueness at the type level: a property, a root model,
the member of an anyOf or oneOf, the items of an array and the values of a
map. An array whose items no set can hold, such as objects or arrays, stays
a list. So does a nested array in a union beside another member of its kind
that keeps its lists, an array beside an array or a map beside a map, as a
msgspec union holds one of each.
Usage
-
--use-unique-items-as-set- the option documented here
Examples
Input Schema:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
minimum: 0
maximum: 100
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
components:
schemas:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
minimum: 0
maximum: 9223372036854775807
name:
type: string
maxLength: 256
tag:
type: string
maxLength: 64
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
maxItems: 10
minItems: 1
uniqueItems: true
UID:
type: integer
minimum: 0
Users:
type: array
items:
required:
- id
- name
- uid
properties:
id:
type: integer
format: int64
minimum: 0
name:
type: string
maxLength: 256
tag:
type: string
maxLength: 64
uid:
$ref: '#/components/schemas/UID'
phones:
type: array
items:
type: string
minLength: 3
maxItems: 10
fax:
type: array
items:
type: string
minLength: 3
height:
type:
- integer
- number
minimum: 1
maximum: 300
weight:
type:
- number
- integer
minimum: 1.0
maximum: 1000.0
age:
type: integer
minimum: 0.0
maximum: 200.0
exclusiveMinimum: true
rating:
type: number
minimum: 0
exclusiveMinimum: true
maximum: 5
Id:
type: string
Rules:
type: array
items:
type: string
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
apis:
type: array
items:
type: object
properties:
apiKey:
type: string
description: To be used as a dataset parameter value
apiVersionNumber:
type: string
description: To be used as a version parameter value
apiUrl:
type: string
format: uri
minLength: 1
description: "The URL describing the dataset's fields"
apiDocumentationUrl:
type: string
format: uri
description: A URL to the API console for each API
Event:
type: object
properties:
name:
type: string
Result:
type: object
properties:
event:
$ref: '#/components/schemas/Event'
Output:
# generated by datamodel-codegen:
# filename: api_constrained.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import AnyUrl, BaseModel, Field, RootModel
class Pet(BaseModel):
__hash__ = object.__hash__
id: int = Field(..., ge=0, le=9223372036854775807)
name: str = Field(..., max_length=256)
tag: str | None = Field(None, max_length=64)
class Pets(RootModel[set[Pet]]):
root: set[Pet] = Field(..., max_length=10, min_length=1)
class UID(RootModel[int]):
root: int = Field(..., ge=0)
class Phone(RootModel[str]):
root: str = Field(..., min_length=3)
class FaxItem(RootModel[str]):
root: str = Field(..., min_length=3)
class User(BaseModel):
id: int = Field(..., ge=0)
name: str = Field(..., max_length=256)
tag: str | None = Field(None, max_length=64)
uid: UID
phones: list[Phone] | None = Field(None, max_length=10)
fax: list[FaxItem] | None = None
height: int | float | None = Field(None, ge=1.0, le=300.0)
weight: float | int | None = Field(None, ge=1.0, le=1000.0)
age: int | None = Field(None, gt=0, le=200)
rating: float | None = Field(None, gt=0.0, le=5.0)
class Users(RootModel[list[User]]):
root: list[User]
class Id(RootModel[str]):
root: str
class Rules(RootModel[list[str]]):
root: list[str]
class Error(BaseModel):
code: int
message: str
class Api(BaseModel):
apiKey: str | None = Field(
None, description='To be used as a dataset parameter value'
)
apiVersionNumber: str | None = Field(
None, description='To be used as a version parameter value'
)
apiUrl: AnyUrl | None = Field(
None, description="The URL describing the dataset's fields"
)
apiDocumentationUrl: AnyUrl | None = Field(
None, description='A URL to the API console for each API'
)
class Apis(RootModel[list[Api]]):
root: list[Api]
class Event(BaseModel):
name: str | None = None
class Result(BaseModel):
event: Event | None = None
--use-unique-items-as-set-by-value¶
Write a uniqueItems set only where its final items hash by value.
Under --use-unique-items-as-set, the arrays whose schemas declare uniqueItems become sets before root models
collapse, type overrides apply and the other modules are processed, and a model that is a set item hashes by identity,
so two equal items are both kept. Deduplication and --reuse-model also compare such arrays as the lists they still
are, so a model whose array declares no uniqueItems can merge into one whose array does, and a list the schema allows
to repeat then drops its duplicates. With --use-unique-items-as-set-by-value the sets are decided on the final item
types: a set is written only where every value of its items hashes by value (scalars, enums, tuples and frozen sets of
them, frozen models whose fields hash), so an array of models that hash only by identity, of Any or of containers
stays a list, and models whose arrays differ in uniqueItems are kept apart.
Usage
datamodel-codegen --input unique_items_by_value.json --use-unique-items-as-set --reuse-model --collapse-reuse-models --collapse-root-models --use-unique-items-as-set-by-value # (1)!
-
--use-unique-items-as-set-by-value- the option documented here
Examples
Input Schema:
{
"title": "Root",
"type": "object",
"properties": {
"labels": {
"$ref": "#/$defs/Labels"
},
"history": {
"$ref": "#/$defs/History"
},
"pets": {
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/$defs/Pet"
}
},
"colors": {
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/$defs/Color"
}
},
"tags": {
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/$defs/Tags"
}
},
"anything": {
"type": "array",
"uniqueItems": true
},
"numbers": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "integer"
},
"default": [
1,
2
]
},
"first": {
"type": "object",
"properties": {
"entry": {
"title": "Entry",
"type": "object",
"properties": {
"tags": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string"
}
}
}
}
}
},
"second": {
"type": "object",
"properties": {
"entry": {
"title": "Entry",
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"codes": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string"
}
},
"settings": {
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/$defs/Settings"
}
},
"pairs": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "array",
"prefixItems": [
{
"type": "integer"
},
{
"type": "string"
}
],
"items": false,
"minItems": 2
}
},
"limits": {
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/$defs/Limits"
}
},
"points": {
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/$defs/Point"
}
}
},
"$defs": {
"Labels": {
"type": "object",
"properties": {
"names": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string"
}
}
}
},
"History": {
"type": "object",
"properties": {
"names": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"Pet": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "integer"
},
"nicknames": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string"
}
}
}
},
"Color": {
"type": "string",
"enum": [
"red",
"blue"
]
},
"Tags": {
"type": "array",
"items": {
"type": "string"
}
},
"Settings": {
"type": "object",
"properties": {
"options": {
"type": "object",
"default": {}
}
}
},
"Limits": {
"type": "object",
"properties": {
"levels": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "integer"
},
"default": [
1
]
}
}
},
"Point": {
"type": "object",
"required": [
"x",
"y"
],
"properties": {
"x": {
"type": "integer"
},
"y": {
"type": "integer"
}
}
}
},
"required": [
"codes"
]
}
Output:
# generated by datamodel-codegen:
# filename: unique_items_by_value.json
from __future__ import annotations
from enum import Enum
from typing import Any
from pydantic import BaseModel, Field, RootModel
class Entry(BaseModel):
tags: set[str] | None = None
class First(BaseModel):
entry: Entry | None = Field(None, title='Entry')
class Entry1(BaseModel):
tags: list[str] | None = None
class Second(BaseModel):
entry: Entry1 | None = Field(None, title='Entry')
class Pair(RootModel[list[int | str]]):
root: list[int | str] = Field(..., max_length=2, min_length=2)
class Labels(BaseModel):
names: set[str] | None = None
class History(BaseModel):
names: list[str] | None = None
class Pet(BaseModel):
id: int
nicknames: set[str] | None = None
class Color(Enum):
red = 'red'
blue = 'blue'
class Settings(BaseModel):
options: dict[str, Any] | None = {}
class Limits(BaseModel):
levels: set[int] | None = {1}
class Point(BaseModel):
x: int
y: int
class Root(BaseModel):
labels: Labels | None = None
history: History | None = None
pets: list[Pet] | None = None
colors: set[Color] | None = None
tags: list[list[str]] | None = None
anything: list[Any] | None = None
numbers: set[int] | None = {1, 2}
first: First | None = None
second: Second | None = None
codes: set[str]
settings: list[Settings] | None = None
pairs: list[Pair] | None = None
limits: list[Limits] | None = None
points: list[Point] | None = None
# generated by datamodel-codegen:
# filename: unique_items_by_value.json
from __future__ import annotations
from enum import Enum
from typing import Any
from pydantic import BaseModel, Field, RootModel
class Entry(BaseModel):
tags: set[str] | None = None
class First(BaseModel):
entry: Entry | None = Field(None, title='Entry')
class Pair(RootModel[list[int | str]]):
__hash__ = object.__hash__
root: list[int | str] = Field(..., max_length=2, min_length=2)
class Labels(BaseModel):
names: set[str] | None = None
class Pet(BaseModel):
__hash__ = object.__hash__
id: int
nicknames: set[str] | None = None
class Color(Enum):
red = 'red'
blue = 'blue'
class Tags(RootModel[list[str]]):
__hash__ = object.__hash__
root: list[str]
class Settings(BaseModel):
__hash__ = object.__hash__
options: dict[str, Any] | None = {}
class Limits(BaseModel):
__hash__ = object.__hash__
levels: set[int] | None = {1}
class Point(BaseModel):
__hash__ = object.__hash__
x: int
y: int
class Root(BaseModel):
labels: Labels | None = None
history: Labels | None = None
pets: set[Pet] | None = None
colors: set[Color] | None = None
tags: set[Tags] | None = None
anything: set[Any] | None = None
numbers: set[int] | None = {1, 2}
first: First | None = None
second: First | None = None
codes: set[str]
settings: set[Settings] | None = None
pairs: set[Pair] | None = None
limits: set[Limits] | None = None
points: set[Point] | None = None
--use-x-python-type-as-written¶
Write a field's x-python-type as given: unions of every spelling and container classes.
An x-python-type types its field where it is not compatible with the schema's type, and a union spelled X | Y, such
as Literal['a', 'b'] | None, never is. Without this option the same union spelled Optional[Literal['a', 'b']] or
Union[Literal['low'], Literal['high']] counts as compatible with every type the schema declares, so it is ignored
and the field takes the schema's str. With it every spelling of a union types the field, at a property, an item, a
map value and a root.
A container class compatible with the schema's type, such as tuple[str, ...], MutableSequence[str], MutableSet,
AbstractSet or MutableMapping, is written as that class around the schema's item, key and value types, which keep
their constraints (tuple[constr(max_length=3), ...]), where without the option it is written as list, Sequence,
set, frozenset or Mapping; --use-generic-container-types and --use-unique-items-as-set no longer rewrite it. A
prefixItems tuple stays a tuple.
Usage
-
--use-x-python-type-as-written- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Settings",
"type": "object",
"properties": {
"mode": {"type": "string", "x-python-type": "Optional[Literal['a', 'b']]"},
"level": {"type": "string", "x-python-type": "typing.Union[typing.Literal['low'], typing.Literal['high']]"},
"spelled": {"type": "string", "x-python-type": "Literal['a', 'b'] | None"},
"modes": {"type": "array", "items": {"type": "string", "x-python-type": "Optional[Literal['a', 'b']]"}},
"by_key": {"type": "object", "additionalProperties": {"type": "string", "x-python-type": "Union[Literal['x'], Literal['y']]"}},
"kind": {"$ref": "#/$defs/Kind"}
},
"$defs": {
"Kind": {"type": "string", "x-python-type": "Optional[Literal['k1', 'k2']]"}
}
}
Output:
# generated by datamodel-codegen:
# filename: x_python_type_unions.json
from __future__ import annotations
from typing import Literal, Optional, Union
from pydantic import BaseModel, RootModel
class Kind(RootModel[Optional[Literal['k1', 'k2']]]):
root: Optional[Literal['k1', 'k2']]
class Settings(BaseModel):
mode: Optional[Literal['a', 'b']] | None = None
level: Union[Literal['low'], Literal['high']] | None = None
spelled: Literal['a', 'b'] | None = None
modes: list[Optional[Literal['a', 'b']]] | None = None
by_key: dict[str, Union[Literal['x'], Literal['y']]] | None = None
kind: Kind | None = None
# generated by datamodel-codegen:
# filename: x_python_type_unions.json
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, RootModel
class Kind(RootModel[str]):
root: str
class Settings(BaseModel):
mode: str | None = None
level: str | None = None
spelled: Literal['a', 'b'] | None = None
modes: list[str] | None = None
by_key: dict[str, str] | None = None
kind: Kind | None = None