🏷️ Field Customization¶
📋 Options¶
| Option | Description |
|---|---|
--aliases |
Apply custom field and class name aliases via inline JSON or... |
--capitalize-enum-members |
Capitalize enum member names to UPPER_CASE format. |
--capitalize-numbered-enum-members |
Capitalize the numbered name an enum member takes when its n... |
--default-values |
Override field default values via inline JSON or a JSON file... |
--deserialize-default-values |
Deserialize selected direct scalar field defaults into their... |
--empty-enum-field-name |
Name for empty string enum field values. |
--extra-fields |
Configure how generated models handle extra fields not defin... |
--field-constraints |
Generate Field() with validation constraints from schema. |
--field-extra-keys |
Include specific extra keys in Field() definitions. |
--field-extra-keys-without-x-prefix |
Include schema extension keys in Field() without requiring '... |
--field-include-all-keys |
Include all schema keys in Field() json_schema_extra. |
--field-type-collision-strategy |
Rename type class instead of field when names collide (Pydan... |
--infer-union-variant-names |
Name inline oneOf/anyOf branch models after the value of the... |
--merge-shared-variant-tags |
Give a variant that discriminated unions tag differently eve... |
--name-allof-union-members-after-branches |
Name the classes an allOf gives the branches of a oneOf or a... |
--no-alias |
Disable Field alias generation for non-Python-safe property ... |
--no-deserialize-default-values |
Keep serialized schema defaults instead of deserializing sel... |
--omit-redundant-constraints |
Do not write a constraint again beside a type that already e... |
--original-field-name-delimiter |
Specify delimiter for original field names when using snake-... |
--read-length-keywords-by-type |
Read the string and the array keywords for their own kind on... |
--read-msgspec-union-bounds-exactly |
Decide the bounds of the int member of a msgspec union on th... |
--remove-special-field-name-prefix |
Remove the special prefix from field names. |
--serialization-aliases |
Apply custom Pydantic v2 serialization aliases via inline JS... |
--set-default-enum-member |
Use the legacy flag for deserializing enum defaults. |
--snake-case-field |
Convert field names to snake_case format. |
--special-field-name-prefix |
Prefix to add to special field names (like reserved keywords... |
--use-attribute-docstrings |
Generate field descriptions as attribute docstrings instead ... |
--use-enum-values-in-discriminator |
Use enum values in discriminator mappings for union types. |
--use-field-description |
Include schema descriptions as Field docstrings. |
--use-field-description-example |
Add field examples to docstrings. |
--use-inline-field-description |
Add field descriptions as inline comments. |
--use-one-model-per-ref-site |
Give an object $ref with sibling keywords one model per pl... |
--use-schema-description |
Use schema description as class docstring. |
--use-serialization-alias |
Use serialization_alias instead of alias for field aliasing ... |
--use-single-line-docstring |
Emit short docstrings on a single line. |
--use-site-models-for-constrained-refs |
Give an allOf of $ref members whose other parts add assert... |
--use-tag-as-union-variant-name |
Name inline oneOf/anyOf branch models after their tag: what ... |
--use-title-as-name |
Use schema title as the generated class name. |
🍳 Recipes¶
Normalize incoming field names¶
Convert source names to Python identifiers while preserving explicit alias data for runtime IO.
Options: --snake-case-field, --original-field-name-delimiter, --aliases
Carry schema documentation into models¶
Promote schema and field descriptions into generated docstrings or field metadata.
Options: --use-schema-description, --use-field-description, --use-field-description-example
--aliases¶
Apply custom field and class name aliases via inline JSON or a JSON file path.
The --aliases option allows renaming fields and classes via an inline JSON object or JSON mapping file,
providing fine-grained control over generated names independent of schema definitions.
See also: Field Aliases
Usage
datamodel-codegen --input api.yaml --aliases openapi/aliases.json --target-python-version 3.10 # (1)!
-
--aliases- 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
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
default: 1
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Users:
type: array
items:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Id:
type: string
Rules:
type: array
items:
type: string
Error:
description: error result
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
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
description: Event object
properties:
name:
type: string
Result:
type: object
properties:
event:
$ref: '#/components/schemas/Event'
Output:
# generated by datamodel-codegen:
# filename: api.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Annotated, TypeAlias
from msgspec import UNSET, Meta, Struct, UnsetType, field
class Pet(Struct):
id_: int = field(name='id')
name_: str = field(name='name')
tag: str | UnsetType = UNSET
Pets: TypeAlias = list[Pet]
class User(Struct):
id_: int = field(name='id')
name_: str = field(name='name')
tag: str | UnsetType = UNSET
Users: TypeAlias = list[User]
Id: TypeAlias = str
Rules: TypeAlias = list[str]
class Error(Struct):
code: int
message: str
class Api(Struct):
apiKey: (
Annotated[str, Meta(description='To be used as a dataset parameter value')]
| UnsetType
) = UNSET
apiVersionNumber: (
Annotated[str, Meta(description='To be used as a version parameter value')]
| UnsetType
) = UNSET
apiUrl: (
Annotated[str, Meta(description="The URL describing the dataset's fields")]
| UnsetType
) = UNSET
apiDocumentationUrl: (
Annotated[str, Meta(description='A URL to the API console for each API')]
| UnsetType
) = UNSET
Apis: TypeAlias = list[Api]
class Event(Struct):
name_: str | UnsetType = field(name='name', default=UNSET)
class Result(Struct):
event: Event | UnsetType = UNSET
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Root",
"properties": {
"name": {
"type": "string"
},
"user": {
"type": "object",
"title": "User",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "integer"
}
}
},
"address": {
"type": "object",
"title": "Address",
"properties": {
"name": {
"type": "string"
},
"city": {
"type": "string"
}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: hierarchical_aliases.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class User(BaseModel):
user_name: str | None = Field(None, alias='name')
id: int | None = None
class Address(BaseModel):
address_name: str | None = Field(None, alias='name')
city: str | None = None
class Root(BaseModel):
root_name: str | None = Field(None, alias='name')
user: User | None = Field(None, title='User')
address: Address | None = Field(None, title='Address')
Input Schema:
Output:
# generated by datamodel-codegen:
# filename: field-aliases.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
DateTime = TypeAliasType("DateTime", 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 DateTimePeriod(BaseModel):
periodFrom: DateTime = Field(..., alias='from')
periodTo: DateTime = Field(..., alias='to')
typename__: Literal['DateTimePeriod'] | None = Field(
'DateTimePeriod', alias='__typename'
)
--capitalize-enum-members¶
Capitalize enum member names to UPPER_CASE format.
The --capitalize-enum-members flag converts enum member names to
UPPER_CASE format (e.g., active becomes ACTIVE), following Python
naming conventions for constants.
Aliases: --capitalise-enum-members | Related: --snake-case-field
Usage
-
--capitalize-enum-members- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "string",
"enum": [
"snake_case",
"CAP_CASE",
"CamelCase",
"UPPERCASE"
]
}
Output:
--capitalize-numbered-enum-members¶
Capitalize the numbered name an enum member takes when its name is taken.
Under --capitalize-enum-members the members a and A both capitalize to A, so the second one is numbered, and
the number goes on the name as written: a_1. With --capitalize-numbered-enum-members the numbered name is
capitalized too: A_1. Without --capitalize-enum-members the option changes nothing.
Aliases: --capitalise-numbered-enum-members | Related: --capitalize-enum-members
Usage
datamodel-codegen --input capitalise_numbered_enum_members.json --capitalize-enum-members --capitalize-numbered-enum-members # (1)!
-
--capitalize-numbered-enum-members- the option documented here
Examples
Input Schema:
{
"title": "Holder",
"type": "object",
"properties": {
"kind": {"type": "string", "enum": ["a", "A", "a_1", "b"]},
"mode": {"type": "string", "enum": ["On", "ON", "on"]}
}
}
Output:
# generated by datamodel-codegen:
# filename: capitalise_numbered_enum_members.json
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel
class Kind(Enum):
A = 'a'
A_1 = 'A'
A_1_1 = 'a_1'
B = 'b'
class Mode(Enum):
ON = 'On'
ON_1 = 'ON'
ON_2 = 'on'
class Holder(BaseModel):
kind: Kind | None = None
mode: Mode | None = None
# generated by datamodel-codegen:
# filename: capitalise_numbered_enum_members.json
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel
class Kind(Enum):
A = 'a'
a_1 = 'A'
A_1 = 'a_1'
B = 'b'
class Mode(Enum):
ON = 'On'
on_1 = 'ON'
on_2 = 'on'
class Holder(BaseModel):
kind: Kind | None = None
mode: Mode | None = None
--default-values¶
Override field default values via inline JSON or a JSON file path.
The --default-values option allows specifying default values for fields via an inline JSON object or JSON file.
Supports scoped format (ClassName.field) for hierarchical overrides.
Usage
datamodel-codegen --input default_values_override.json --default-values default_values/scoped_defaults.json # (1)!
-
--default-values- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"User": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"page": {
"type": "integer"
}
},
"required": ["name"]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: default_values_override.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, RootModel
class Model(RootModel[Any]):
root: Any
class User(BaseModel):
name: str
status: str | None = 'active'
page: int | None = 1
--deserialize-default-values¶
Deserialize selected direct scalar field defaults into their generated Python types.
The --deserialize-default-values option accepts an explicit list of generated value types. For example,
--deserialize-default-values decimal emits a direct Decimal field's valid string default as a Decimal value,
while --deserialize-default-values enum emits matching scalar and list defaults as enum members. Defaults that
cannot be deserialized remain serialized so the generated module stays importable.
Usage
datamodel-codegen --input serialized_decimal_defaults.json --deserialize-default-values decimal --target-python-version 3.10 # (1)!
-
--deserialize-default-values- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Invoice",
"type": "object",
"properties": {
"amount": {
"type": "string",
"format": "decimal",
"default": "12.340"
},
"invalid_amount": {
"type": "string",
"format": "decimal",
"default": "not-a-decimal"
},
"nullable_amount": {
"type": ["string", "null"],
"format": "decimal",
"default": null
},
"label": {
"type": "string",
"default": "retail"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: serialized_decimal_defaults.json
from __future__ import annotations
from decimal import Decimal
from pydantic import BaseModel
class Invoice(BaseModel):
amount: Decimal | None = Decimal('12.340')
invalid_amount: Decimal | None = 'not-a-decimal'
nullable_amount: Decimal | None = None
label: str | None = 'retail'
# generated by datamodel-codegen:
# filename: serialized_decimal_defaults.json
from __future__ import annotations
from decimal import Decimal
from pydantic.dataclasses import dataclass
@dataclass
class Invoice:
amount: Decimal | None = Decimal('12.340')
invalid_amount: Decimal | None = 'not-a-decimal'
nullable_amount: Decimal | None = None
label: str | None = 'retail'
# generated by datamodel-codegen:
# filename: serialized_decimal_defaults.json
from __future__ import annotations
from dataclasses import dataclass
from decimal import Decimal
@dataclass
class Invoice:
amount: Decimal | None = Decimal('12.340')
invalid_amount: Decimal | None = 'not-a-decimal'
nullable_amount: Decimal | None = None
label: str | None = 'retail'
# generated by datamodel-codegen:
# filename: serialized_decimal_defaults.json
from __future__ import annotations
from decimal import Decimal
from typing import TypedDict
from typing_extensions import NotRequired
class Invoice(TypedDict):
amount: NotRequired[Decimal]
invalid_amount: NotRequired[Decimal]
nullable_amount: NotRequired[Decimal | None]
label: NotRequired[str]
# generated by datamodel-codegen:
# filename: serialized_decimal_defaults.json
from __future__ import annotations
from decimal import Decimal
from msgspec import UNSET, Struct, UnsetType
class Invoice(Struct):
amount: Decimal | UnsetType = Decimal('12.340')
invalid_amount: Decimal | UnsetType = 'not-a-decimal'
nullable_amount: Decimal | None | UnsetType = UNSET
label: str | UnsetType = 'retail'
--empty-enum-field-name¶
Name for empty string enum field values.
The --empty-enum-field-name flag configures the code generation behavior.
Usage
-
--empty-enum-field-name- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "string",
"enum": [
true,
false,
"",
"\n",
"\r\n",
"\t",
"\\x08",
null,
"\\"
]
}
Output:
# generated by datamodel-codegen:
# filename: special_enum.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import RootModel
class ModelEnum(Enum):
True_ = True
False_ = False
empty = ''
field_ = '\n'
field__ = '\r\n'
field__1 = '\t'
field_x08 = '\\x08'
field__2 = '\\'
class Model(RootModel[ModelEnum | None]):
root: ModelEnum | None = None
--extra-fields¶
Configure how generated models handle extra fields not defined in schema.
The --extra-fields flag sets the generated models to allow, forbid, or
ignore extra fields. With --extra-fields allow, models will accept and
store fields not defined in the schema. Options: allow, ignore, forbid.
Usage
-
--extra-fields- the option documented here
Examples
Input Schema:
type Person {
id: ID!
name: String!
height: Int
mass: Int
hair_color: String
skin_color: String
eye_color: String
birth_year: String
gender: String
# Relationships
homeworld_id: ID
homeworld: Planet
species: [Species!]!
species_ids: [ID!]!
films: [Film!]!
films_ids: [ID!]!
starships: [Starship!]!
starships_ids: [ID!]!
vehicles: [Vehicle!]!
vehicles_ids: [ID!]!
}
type Planet {
id: ID!
name: String!
rotation_period: String
orbital_period: String
diameter: String
climate: String
gravity: String
terrain: String
surface_water: String
population: String
# Relationships
residents: [Person!]!
residents_ids: [ID!]!
films: [Film!]!
films_ids: [ID!]!
}
type Species {
id: ID!
name: String!
classification: String
designation: String
average_height: String
skin_colors: String
hair_colors: String
eye_colors: String
average_lifespan: String
language: String
# Relationships
people: [Person!]!
people_ids: [ID!]!
films: [Film!]!
films_ids: [ID!]!
}
type Vehicle {
id: ID!
name: String!
model: String
manufacturer: String
cost_in_credits: String
length: String
max_atmosphering_speed: String
crew: String
passengers: String
cargo_capacity: String
consumables: String
vehicle_class: String
# Relationships
pilots: [Person!]!
pilots_ids: [ID!]!
films: [Film!]!
films_ids: [ID!]!
}
type Starship {
id: ID!
name: String!
model: String
manufacturer: String
cost_in_credits: String
length: String
max_atmosphering_speed: String
crew: String
passengers: String
cargo_capacity: String
consumables: String
hyperdrive_rating: String
MGLT: String
starship_class: String
# Relationships
pilots: [Person!]!
pilots_ids: [ID!]!
films: [Film!]!
films_ids: [ID!]!
}
type Film {
id: ID!
title: String!
episode_id: Int!
opening_crawl: String!
director: String!
producer: String
release_date: String!
# Relationships
characters: [Person!]!
characters_ids: [ID!]!
planets: [Planet!]!
planets_ids: [ID!]!
starships: [Starship!]!
starships_ids: [ID!]!
vehicles: [Vehicle!]!
vehicles_ids: [ID!]!
species: [Species!]!
species_ids: [ID!]!
}
type Query {
planet(id: ID!): Planet
listPlanets(page: Int): [Planet!]!
person(id: ID!): Person
listPeople(page: Int): [Person!]!
species(id: ID!): Species
listSpecies(page: Int): [Species!]!
film(id: ID!): Film
listFilms(page: Int): [Film!]!
starship(id: ID!): Starship
listStarships(page: Int): [Starship!]!
vehicle(id: ID!): Vehicle
listVehicles(page: Int): [Vehicle!]!
}
Output:
# generated by datamodel-codegen:
# filename: simple-star-wars.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field
from typing_extensions import TypeAliasType
Boolean = TypeAliasType("Boolean", bool)
"""
The `Boolean` scalar type represents `true` or `false`.
"""
ID = TypeAliasType("ID", str)
"""
The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
"""
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.
"""
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 Film(BaseModel):
model_config = ConfigDict(
extra='allow',
)
characters: list[Person]
characters_ids: list[ID]
director: String
episode_id: Int
id: ID
opening_crawl: String
planets: list[Planet]
planets_ids: list[ID]
producer: String | None = None
release_date: String
species: list[Species]
species_ids: list[ID]
starships: list[Starship]
starships_ids: list[ID]
title: String
vehicles: list[Vehicle]
vehicles_ids: list[ID]
typename__: Literal['Film'] | None = Field('Film', alias='__typename')
class Person(BaseModel):
model_config = ConfigDict(
extra='allow',
)
birth_year: String | None = None
eye_color: String | None = None
films: list[Film]
films_ids: list[ID]
gender: String | None = None
hair_color: String | None = None
height: Int | None = None
homeworld: Planet | None = None
homeworld_id: ID | None = None
id: ID
mass: Int | None = None
name: String
skin_color: String | None = None
species: list[Species]
species_ids: list[ID]
starships: list[Starship]
starships_ids: list[ID]
vehicles: list[Vehicle]
vehicles_ids: list[ID]
typename__: Literal['Person'] | None = Field('Person', alias='__typename')
class Planet(BaseModel):
model_config = ConfigDict(
extra='allow',
)
climate: String | None = None
diameter: String | None = None
films: list[Film]
films_ids: list[ID]
gravity: String | None = None
id: ID
name: String
orbital_period: String | None = None
population: String | None = None
residents: list[Person]
residents_ids: list[ID]
rotation_period: String | None = None
surface_water: String | None = None
terrain: String | None = None
typename__: Literal['Planet'] | None = Field('Planet', alias='__typename')
class Species(BaseModel):
model_config = ConfigDict(
extra='allow',
)
average_height: String | None = None
average_lifespan: String | None = None
classification: String | None = None
designation: String | None = None
eye_colors: String | None = None
films: list[Film]
films_ids: list[ID]
hair_colors: String | None = None
id: ID
language: String | None = None
name: String
people: list[Person]
people_ids: list[ID]
skin_colors: String | None = None
typename__: Literal['Species'] | None = Field('Species', alias='__typename')
class Starship(BaseModel):
model_config = ConfigDict(
extra='allow',
)
MGLT: String | None = None
cargo_capacity: String | None = None
consumables: String | None = None
cost_in_credits: String | None = None
crew: String | None = None
films: list[Film]
films_ids: list[ID]
hyperdrive_rating: String | None = None
id: ID
length: String | None = None
manufacturer: String | None = None
max_atmosphering_speed: String | None = None
model: String | None = None
name: String
passengers: String | None = None
pilots: list[Person]
pilots_ids: list[ID]
starship_class: String | None = None
typename__: Literal['Starship'] | None = Field('Starship', alias='__typename')
class Vehicle(BaseModel):
model_config = ConfigDict(
extra='allow',
)
cargo_capacity: String | None = None
consumables: String | None = None
cost_in_credits: String | None = None
crew: String | None = None
films: list[Film]
films_ids: list[ID]
id: ID
length: String | None = None
manufacturer: String | None = None
max_atmosphering_speed: String | None = None
model: String | None = None
name: String
passengers: String | None = None
pilots: list[Person]
pilots_ids: list[ID]
vehicle_class: String | None = None
typename__: Literal['Vehicle'] | None = Field('Vehicle', alias='__typename')
Film.model_rebuild()
Person.model_rebuild()
--field-constraints¶
Generate Field() with validation constraints from schema.
The --field-constraints flag generates Pydantic Field() definitions with
validation constraints (min/max length, pattern, etc.) from the schema.
Related: --strict-types
See also: Field Constraints
Usage
-
--field-constraints- 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):
id: int = Field(..., ge=0, le=9223372036854775807)
name: str = Field(..., max_length=256)
tag: str | None = Field(None, max_length=64)
class Pets(RootModel[list[Pet]]):
root: list[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
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,
StrictBytes,
StrictFloat,
StrictInt,
StrictStr,
)
class User(BaseModel):
name: StrictStr | None = Field(None, examples=['ken'])
age: StrictInt | None = None
salary: StrictInt | None = Field(None, ge=0)
debt: StrictInt | None = Field(None, le=0)
loan: StrictFloat | None = Field(None, le=0.0)
tel: StrictStr | None = Field(None, pattern='^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$')
height: StrictFloat | None = Field(None, ge=0.0)
weight: StrictFloat | None = Field(None, ge=0.0)
score: StrictFloat | None = Field(None, ge=1e-08)
active: StrictBool | None = None
photo: StrictBytes | None = Field(None, min_length=100)
--field-extra-keys¶
Include specific extra keys in Field() definitions.
The --field-extra-keys flag configures the code generation behavior.
Usage
datamodel-codegen --input extras.json --field-extra-keys key2 --field-extra-keys-without-x-prefix x-repr # (1)!
-
--field-extra-keys- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Extras",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "normal key",
"key1": 123,
"key2": 456,
"$exclude": 123,
"invalid-key-1": "abc",
"-invalid+key_2": "efg",
"$comment": "comment",
"$id": "#name",
"register": "hij",
"schema": "klm",
"x-repr": true,
"x-abc": true,
"example": "example",
"readOnly": true
},
"age": {
"type": "integer",
"example": 12,
"writeOnly": true,
"examples": [
13,
20
]
},
"status": {
"type": "string",
"examples": [
"active"
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: extras.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class Extras(BaseModel):
name: str | None = Field(
None,
description='normal key',
examples=['example'],
json_schema_extra={'key2': 456, 'invalid-key-1': 'abc'},
repr=True,
)
age: int | None = Field(None, examples=[13, 20], json_schema_extra={'example': 12})
status: str | None = Field(None, examples=['active'])
--field-extra-keys-without-x-prefix¶
Include schema extension keys in Field() without requiring 'x-' prefix.
The --field-extra-keys-without-x-prefix option allows you to specify custom schema extension keys that should be included in Pydantic Field() extras without the 'x-' prefix requirement. For example, 'x-repr' in the schema becomes 'repr' in Field(). This is useful for custom schema extensions and vendor-specific metadata.
Usage
datamodel-codegen --input extras.json --field-include-all-keys --field-extra-keys-without-x-prefix x-repr # (1)!
-
--field-extra-keys-without-x-prefix- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Extras",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "normal key",
"key1": 123,
"key2": 456,
"$exclude": 123,
"invalid-key-1": "abc",
"-invalid+key_2": "efg",
"$comment": "comment",
"$id": "#name",
"register": "hij",
"schema": "klm",
"x-repr": true,
"x-abc": true,
"example": "example",
"readOnly": true
},
"age": {
"type": "integer",
"example": 12,
"writeOnly": true,
"examples": [
13,
20
]
},
"status": {
"type": "string",
"examples": [
"active"
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: extras.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class Extras(BaseModel):
name: str | None = Field(
None,
description='normal key',
examples=['example'],
json_schema_extra={
'key1': 123,
'key2': 456,
'$exclude': 123,
'invalid-key-1': 'abc',
'-invalid+key_2': 'efg',
'$comment': 'comment',
'register': 'hij',
'schema': 'klm',
'x-abc': True,
'readOnly': True,
},
repr=True,
)
age: int | None = Field(
None, examples=[13, 20], json_schema_extra={'example': 12, 'writeOnly': True}
)
status: str | None = Field(None, examples=['active'])
--field-include-all-keys¶
Include all schema keys in Field() json_schema_extra.
The --field-include-all-keys flag configures the code generation behavior.
Usage
-
--field-include-all-keys- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": ["string", "null"],
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
},
"friends": {
"type": "array"
},
"comment": {
"type": "null"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: person.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field, conint
class Person(BaseModel):
firstName: str | None = Field(None, description="The person's first name.")
lastName: str | None = Field(None, description="The person's last name.")
age: conint(ge=0) | None = Field(
None, description='Age in years which must be equal to or greater than zero.'
)
friends: list[Any] | None = None
comment: None = Field(None)
--field-type-collision-strategy¶
Rename type class instead of field when names collide (Pydantic v2 only).
The --field-type-collision-strategy flag controls how field name and type name
collisions are resolved. With rename-type, the type class is renamed with a suffix
to preserve the original field name, instead of renaming the field and adding an alias.
Usage
datamodel-codegen --input field_has_same_name.json --output-model-type pydantic_v2.BaseModel --field-type-collision-strategy rename-type # (1)!
-
--field-type-collision-strategy- the option documented here
Examples
Input Schema:
{
"title": "Test",
"type": "object",
"properties": {
"TestObject": {
"title": "TestObject",
"type": "object",
"properties": {
"test_string": {
"type": "string"
}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: field_has_same_name.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class TestObject_1(BaseModel):
test_string: str | None = None
class Test(BaseModel):
TestObject: TestObject_1 | None = Field(None, title='TestObject')
--infer-union-variant-names¶
Name inline oneOf/anyOf branch models after the value of their tag field (Pet + type: "cat" -> PetCat) instead of Pet1, Pet2.
The --infer-union-variant-names flag uses branch-local const values or
single-value enums on a shared discriminator-style property to name generated
inline union models. This is useful when inline union branches would otherwise
receive position-based names such as Event and Event1.
The literal value can also come from a single-value enum or an internal $ref.
At least two branches need distinct values on the field; to also name a union's
only tagged branch and branches tagged by their only key, use
--use-tag-as-union-variant-name.
Existing generated output is preserved unless this option is enabled.
Related: --use-tag-as-union-variant-name, --use-title-as-name
Usage
-
--infer-union-variant-names- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "WebhookEnvelope",
"type": "object",
"required": ["event"],
"properties": {
"event": {
"oneOf": [
{
"type": "object",
"required": ["type", "id"],
"properties": {
"type": {"const": "message.created"},
"id": {"type": "string"}
}
},
{
"type": "object",
"required": ["type", "reason"],
"properties": {
"type": {"const": "message.failed"},
"reason": {"type": "string"}
}
}
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: infer_union_variant_names.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel
class EventMessageCreated(BaseModel):
type: Literal['message.created']
id: str
class EventMessageFailed(BaseModel):
type: Literal['message.failed']
reason: str
class WebhookEnvelope(BaseModel):
event: EventMessageCreated | EventMessageFailed
# generated by datamodel-codegen:
# filename: infer_union_variant_names.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel
class Event(BaseModel):
type: Literal['message.created']
id: str
class Event1(BaseModel):
type: Literal['message.failed']
reason: str
class WebhookEnvelope(BaseModel):
event: Event | Event1
--merge-shared-variant-tags¶
Give a variant that discriminated unions tag differently every tag they give it.
A variant that several discriminated unions list has one tag field. Without the option it keeps the tags of the first
union that tags it, so a union that tags it otherwise, by a mapping key or by the schema name, rejects the documents
that select the variant by a tag it does not keep, and a warning says so. With --merge-shared-variant-tags its tag
field is a Literal of every tag the unions give it, so each union decodes the documents it selects the variant by; a
union then also accepts the tags the other unions give the variant. A tag that the pattern of the tag field rejects is
left out, as the schema rejects the documents it selects the variant by. A variant keeps the first union's tags where a
union listing it, or nesting a union that lists it, would then read one of its tags on another variant, as crossing
mappings do, and msgspec Structs, which take one tag, are unchanged.
Usage
-
--merge-shared-variant-tags- the option documented here
Examples
Input Schema:
openapi: 3.0.3
info:
title: Variants Shared by Discriminated Unions
version: 1.0.0
paths: {}
components:
schemas:
Holder:
type: object
properties:
byName:
$ref: '#/components/schemas/ByName'
byKey:
$ref: '#/components/schemas/ByKey'
stock:
$ref: '#/components/schemas/Stock'
herd:
$ref: '#/components/schemas/Herd'
pet:
$ref: '#/components/schemas/Pet'
animal:
$ref: '#/components/schemas/Animal'
forward:
$ref: '#/components/schemas/Forward'
backward:
$ref: '#/components/schemas/Backward'
mixed:
$ref: '#/components/schemas/Mixed'
Cat:
type: object
required: [kind]
properties:
kind: {type: string}
meow: {type: string}
Dog:
type: object
required: [kind]
properties:
kind: {type: string}
bark: {type: string}
ByName:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
discriminator:
propertyName: kind
ByKey:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
discriminator:
propertyName: kind
mapping:
cat: '#/components/schemas/Cat'
dog: '#/components/schemas/Dog'
Cow:
type: object
required: [kind]
properties:
kind: {type: string}
moo: {type: string}
Pig:
type: object
required: [kind]
properties:
kind: {type: string}
oink: {type: string}
Stock:
oneOf:
- $ref: '#/components/schemas/Cow'
- $ref: '#/components/schemas/Pig'
discriminator:
propertyName: kind
mapping:
cow: '#/components/schemas/Cow'
pig: '#/components/schemas/Pig'
Herd:
oneOf:
- $ref: '#/components/schemas/Cow'
- $ref: '#/components/schemas/Pig'
discriminator:
propertyName: kind
Fox:
type: object
required: [kind]
properties:
kind: {type: string}
den: {type: string}
Owl:
type: object
required: [kind]
properties:
kind: {type: string}
nest: {type: string}
Pet:
oneOf:
- $ref: '#/components/schemas/Fox'
- $ref: '#/components/schemas/Owl'
discriminator:
propertyName: kind
mapping:
fox: '#/components/schemas/Fox'
owl: '#/components/schemas/Owl'
Animal:
oneOf:
- $ref: '#/components/schemas/Fox'
- $ref: '#/components/schemas/Owl'
discriminator:
propertyName: kind
mapping:
vulpine: '#/components/schemas/Fox'
avian: '#/components/schemas/Owl'
Red:
type: object
required: [kind]
properties:
kind: {type: string}
hue: {type: integer}
Blue:
type: object
required: [kind]
properties:
kind: {type: string}
depth: {type: integer}
Forward:
oneOf:
- $ref: '#/components/schemas/Red'
- $ref: '#/components/schemas/Blue'
discriminator:
propertyName: kind
mapping:
a: '#/components/schemas/Red'
b: '#/components/schemas/Blue'
Backward:
oneOf:
- $ref: '#/components/schemas/Red'
- $ref: '#/components/schemas/Blue'
discriminator:
propertyName: kind
mapping:
b: '#/components/schemas/Red'
a: '#/components/schemas/Blue'
Name:
type: string
Mixed:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Name'
discriminator:
propertyName: kind
Output:
# generated by datamodel-codegen:
# filename: discriminator_merged_variant_tags.yaml
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field, RootModel
class Cat(BaseModel):
kind: Literal['Cat', 'cat']
meow: str | None = None
class Dog(BaseModel):
kind: Literal['Dog', 'dog']
bark: str | None = None
class ByName(RootModel[Cat | Dog]):
root: Cat | Dog = Field(..., discriminator='kind')
class ByKey(RootModel[Cat | Dog]):
root: Cat | Dog = Field(..., discriminator='kind')
class Cow(BaseModel):
kind: Literal['cow', 'Cow']
moo: str | None = None
class Pig(BaseModel):
kind: Literal['pig', 'Pig']
oink: str | None = None
class Stock(RootModel[Cow | Pig]):
root: Cow | Pig = Field(..., discriminator='kind')
class Herd(RootModel[Cow | Pig]):
root: Cow | Pig = Field(..., discriminator='kind')
class Fox(BaseModel):
kind: Literal['fox', 'vulpine']
den: str | None = None
class Owl(BaseModel):
kind: Literal['owl', 'avian']
nest: str | None = None
class Pet(RootModel[Fox | Owl]):
root: Fox | Owl = Field(..., discriminator='kind')
class Animal(RootModel[Fox | Owl]):
root: Fox | Owl = Field(..., discriminator='kind')
class Red(BaseModel):
kind: Literal['a']
hue: int | None = None
class Blue(BaseModel):
kind: Literal['b']
depth: int | None = None
class Forward(RootModel[Red | Blue]):
root: Red | Blue = Field(..., discriminator='kind')
class Backward(RootModel[Red | Blue]):
root: Red | Blue = Field(..., discriminator='kind')
class Name(RootModel[str]):
root: str
class Mixed(RootModel[Cat | Name]):
root: Cat | Name
class Holder(BaseModel):
byName: ByName | None = None
byKey: ByKey | None = None
stock: Stock | None = None
herd: Herd | None = None
pet: Pet | None = None
animal: Animal | None = None
forward: Forward | None = None
backward: Backward | None = None
mixed: Mixed | None = None
# generated by datamodel-codegen:
# filename: discriminator_merged_variant_tags.yaml
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field, RootModel
class Cat(BaseModel):
kind: Literal['Cat']
meow: str | None = None
class Dog(BaseModel):
kind: Literal['Dog']
bark: str | None = None
class ByName(RootModel[Cat | Dog]):
root: Cat | Dog = Field(..., discriminator='kind')
class ByKey(RootModel[Cat | Dog]):
root: Cat | Dog = Field(..., discriminator='kind')
class Cow(BaseModel):
kind: Literal['cow']
moo: str | None = None
class Pig(BaseModel):
kind: Literal['pig']
oink: str | None = None
class Stock(RootModel[Cow | Pig]):
root: Cow | Pig = Field(..., discriminator='kind')
class Herd(RootModel[Cow | Pig]):
root: Cow | Pig = Field(..., discriminator='kind')
class Fox(BaseModel):
kind: Literal['fox']
den: str | None = None
class Owl(BaseModel):
kind: Literal['owl']
nest: str | None = None
class Pet(RootModel[Fox | Owl]):
root: Fox | Owl = Field(..., discriminator='kind')
class Animal(RootModel[Fox | Owl]):
root: Fox | Owl = Field(..., discriminator='kind')
class Red(BaseModel):
kind: Literal['a']
hue: int | None = None
class Blue(BaseModel):
kind: Literal['b']
depth: int | None = None
class Forward(RootModel[Red | Blue]):
root: Red | Blue = Field(..., discriminator='kind')
class Backward(RootModel[Red | Blue]):
root: Red | Blue = Field(..., discriminator='kind')
class Name(RootModel[str]):
root: str
class Mixed(RootModel[Cat | Name]):
root: Cat | Name
class Holder(BaseModel):
byName: ByName | None = None
byKey: ByKey | None = None
stock: Stock | None = None
herd: Herd | None = None
pet: Pet | None = None
animal: Animal | None = None
forward: Forward | None = None
backward: Backward | None = None
mixed: Mixed | None = None
--name-allof-union-members-after-branches¶
Name the classes an allOf gives the branches of a oneOf or anyOf it holds after the branches.
An allOf that holds a oneOf or anyOf gives each branch a class that combines it with the other parts of the allOf.
These classes are numbered after the holder, Event1 to Event5 for two branches, and --infer-union-variant-names
names the branch-only bases after their tags, not the classes of the union. With
--name-allof-union-members-after-branches each class of the union takes the holder's name and the branch's tag
(under --infer-union-variant-names or --use-tag-as-union-variant-name), the class of a $ref branch, or its
position (EventCreated, NoticeOpened, Event1), a branch-only base takes the class's name and Base
(EventCreatedBase), and the part the branches share takes the holder's name and Base (EventBase).
Related: --infer-union-variant-names, --naming-strategy, --use-tag-as-union-variant-name
Usage
datamodel-codegen --input allof_union_members.yaml --name-allof-union-members-after-branches --infer-union-variant-names # (1)!
-
--name-allof-union-members-after-branches- the option documented here
Examples
Input Schema:
openapi: 3.1.0
info: {title: allOf union members, version: "1"}
paths: {}
components:
schemas:
Envelope:
type: object
required: [id]
properties:
id: {type: string}
Event:
allOf:
- $ref: '#/components/schemas/Envelope'
- oneOf:
- type: object
required: [type]
properties:
type: {type: string, enum: [created]}
name: {type: string}
- type: object
required: [type]
properties:
type: {type: string, enum: [deleted]}
reason: {type: string}
Opened:
type: object
required: [state]
properties:
state: {type: string, enum: [opened]}
Closed:
type: object
required: [state]
properties:
state: {type: string, enum: [closed]}
Notice:
allOf:
- $ref: '#/components/schemas/Envelope'
- oneOf:
- $ref: '#/components/schemas/Opened'
- $ref: '#/components/schemas/Closed'
Output:
# generated by datamodel-codegen:
# filename: allof_union_members.yaml
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, RootModel
class Envelope(BaseModel):
id: str
class Type(Enum):
created = 'created'
class EventCreatedBase(BaseModel):
type: Type
name: str | None = None
class Type1(Enum):
deleted = 'deleted'
class EventDeletedBase(BaseModel):
type: Type1
reason: str | None = None
class EventBase(Envelope):
pass
class EventCreated(EventCreatedBase, EventBase):
pass
class EventDeleted(EventDeletedBase, EventBase):
pass
class Event(RootModel[EventCreated | EventDeleted]):
root: EventCreated | EventDeleted
class State(Enum):
opened = 'opened'
class Opened(BaseModel):
state: State
class State1(Enum):
closed = 'closed'
class Closed(BaseModel):
state: State1
class NoticeBase(Envelope):
pass
class NoticeOpened(Opened, NoticeBase):
pass
class NoticeClosed(Closed, NoticeBase):
pass
class Notice(RootModel[NoticeOpened | NoticeClosed]):
root: NoticeOpened | NoticeClosed
# generated by datamodel-codegen:
# filename: allof_union_members.yaml
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, RootModel
class Envelope(BaseModel):
id: str
class Type(Enum):
created = 'created'
class EventCreated(BaseModel):
type: Type
name: str | None = None
class Type1(Enum):
deleted = 'deleted'
class EventDeleted(BaseModel):
type: Type1
reason: str | None = None
class Event1(Envelope):
pass
class Event2(EventCreated, Event1):
pass
class Event3(EventDeleted, Event1):
pass
class Event(RootModel[Event2 | Event3]):
root: Event2 | Event3
class State(Enum):
opened = 'opened'
class Opened(BaseModel):
state: State
class State1(Enum):
closed = 'closed'
class Closed(BaseModel):
state: State1
class Notice1(Envelope):
pass
class Notice2(Opened, Notice1):
pass
class Notice3(Closed, Notice1):
pass
class Notice(RootModel[Notice2 | Notice3]):
root: Notice2 | Notice3
--no-alias¶
Disable Field alias generation for non-Python-safe property names.
The --no-alias flag disables automatic alias generation when JSON property
names contain characters invalid in Python (like hyphens). Without this flag,
fields are renamed to Python-safe names with Field(alias='original-name').
With this flag, only Python-safe names are used without aliases.
See also: Field Aliases
Usage
-
--no-alias- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"first-name": {
"type": "string"
},
"last-name": {
"type": "string"
},
"email_address": {
"type": "string"
}
},
"required": ["first-name", "last-name"]
}
Output:
# generated by datamodel-codegen:
# filename: no_alias.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class Person(BaseModel):
first_name: str = Field(..., alias='first-name')
last_name: str = Field(..., alias='last-name')
email_address: str | None = None
--no-deserialize-default-values¶
Keep serialized schema defaults instead of deserializing selected types.
The --no-deserialize-default-values flag explicitly disables default-value deserialization, including when a
preset enables it. Compatibility warnings still identify direct scalar defaults whose serialized form does not
match the generated Python type.
Related: --deserialize-default-values, --preset
Usage
datamodel-codegen --input serialized_decimal_defaults.json --preset standard-py310-20260826 --no-deserialize-default-values --disable-timestamp --formatters builtin # (1)!
-
--no-deserialize-default-values- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Invoice",
"type": "object",
"properties": {
"amount": {
"type": "string",
"format": "decimal",
"default": "12.340"
},
"invalid_amount": {
"type": "string",
"format": "decimal",
"default": "not-a-decimal"
},
"nullable_amount": {
"type": ["string", "null"],
"format": "decimal",
"default": null
},
"label": {
"type": "string",
"default": "retail"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: serialized_decimal_defaults.json
from __future__ import annotations
from decimal import Decimal
from pydantic import BaseModel, ConfigDict
class Invoice(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
amount: Decimal = '12.340'
invalid_amount: Decimal = 'not-a-decimal'
nullable_amount: Decimal | None = None
label: str = 'retail'
--omit-redundant-constraints¶
Do not write a constraint again beside a type that already enforces it.
In the field forms (--field-constraints, --use-annotated), a zero-bound class from
--use-non-positive-negative-number-constrained-types, such as NonNegativeInt, enforces its bound, so a nullable
field, a root model or an item writes NonNegativeInt | None instead of repeating Field(ge=0); under
--strict-types the field writes the bound beside StrictInt instead of a strict conint. The Literal of a const
or an enum enforces the length and number constraints beside it by its values: values that violate them are left
out and the field writes none of them, and a const branch of a oneOf or anyOf whose constraints its value meets stays
a Literal instead of a root model. A pattern and a multipleOf the check cannot decide stay written.
Usage
datamodel-codegen --input redundant_constraints.json --use-annotated --use-non-positive-negative-number-constrained-types --use-single-value-enum-as-const --omit-redundant-constraints # (1)!
-
--omit-redundant-constraints- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "RedundantConstraints",
"type": "object",
"$defs": {
"Count": {"type": "integer", "minimum": 0},
"NullableCount": {"type": ["integer", "null"], "minimum": 0},
"Bounded": {"type": "integer", "minimum": 0, "maximum": 9},
"Ratio": {"type": "number", "exclusiveMinimum": 0},
"ModelIds": {"anyOf": [{"type": "string", "minLength": 1}, {"type": "string", "enum": ["gpt-live-1"]}]},
"ConstIds": {"anyOf": [{"type": "string", "minLength": 1}, {"type": "string", "const": "gpt-live-1"}]},
"Code": {"type": "string", "const": "abc", "minLength": 1},
"Level": {"type": "string", "enum": ["a", "bb", "ccc"], "minLength": 2}
},
"properties": {
"count": {"type": ["integer", "null"], "minimum": 0},
"plain": {"type": "integer", "minimum": 0},
"negative": {"type": ["integer", "null"], "exclusiveMaximum": 0},
"positive": {"type": ["number", "null"], "exclusiveMinimum": 0},
"both": {"type": ["integer", "null"], "minimum": 0, "maximum": 10},
"counts": {"type": "array", "items": {"type": ["integer", "null"], "minimum": 0}},
"root_count": {"$ref": "#/$defs/Count"},
"nullable_count": {"$ref": "#/$defs/NullableCount"},
"bounded": {"$ref": "#/$defs/Bounded"},
"ratio": {"$ref": "#/$defs/Ratio"},
"model": {"$ref": "#/$defs/ModelIds", "minLength": 1},
"const_model": {"$ref": "#/$defs/ConstIds", "minLength": 1},
"direct": {"type": "string", "const": "abc", "minLength": 1},
"number": {"type": "integer", "const": 5, "minimum": 1},
"codes": {"type": "array", "items": {"type": "string", "const": "abc", "minLength": 2}},
"code": {"$ref": "#/$defs/Code"},
"level": {"$ref": "#/$defs/Level"},
"unmet": {"type": "string", "const": "abc", "maxLength": 2},
"ratios": {"type": "array", "items": {"type": "number", "const": 1.5, "minimum": 1}},
"patterned": {"type": "array", "items": {"type": "string", "const": "abc", "pattern": "^a", "minLength": 1}}
}
}
Output:
# generated by datamodel-codegen:
# filename: redundant_constraints.json
from __future__ import annotations
from enum import Enum
from typing import Annotated, Literal
from pydantic import (
BaseModel,
Field,
NegativeInt,
NonNegativeInt,
PositiveFloat,
RootModel,
)
class Count(RootModel[NonNegativeInt | None]):
root: NonNegativeInt | None
class Model(RootModel[str]):
root: Annotated[str, Field(min_length=1)]
class ConstModel(RootModel[str]):
root: Annotated[str, Field(min_length=1)]
class Ratio1(RootModel[float]):
root: Annotated[float, Field(ge=1.0)]
class CountModel(RootModel[NonNegativeInt]):
root: NonNegativeInt
class NullableCount(RootModel[NonNegativeInt | None]):
root: NonNegativeInt | None
class Bounded(RootModel[NonNegativeInt]):
root: Annotated[NonNegativeInt, Field(le=9)]
class Ratio(RootModel[PositiveFloat]):
root: PositiveFloat
class ModelIds1(RootModel[str]):
root: Annotated[str, Field(min_length=1)]
class ModelIds(RootModel[ModelIds1 | Literal['gpt-live-1']]):
root: ModelIds1 | Literal['gpt-live-1']
class ConstIds1(RootModel[str]):
root: Annotated[str, Field(min_length=1)]
class ConstIds(RootModel[ConstIds1 | Literal['gpt-live-1']]):
root: ConstIds1 | Literal['gpt-live-1']
class Code(RootModel[Literal['abc']]):
root: Literal['abc']
class Level(Enum):
bb = 'bb'
ccc = 'ccc'
class RedundantConstraints(BaseModel):
count: NonNegativeInt | None = None
plain: NonNegativeInt | None = None
negative: NegativeInt | None = None
positive: PositiveFloat | None = None
both: Annotated[NonNegativeInt | None, Field(le=10)] = None
counts: list[Count | None] | None = None
root_count: CountModel | None = None
nullable_count: NullableCount | None = None
bounded: Bounded | None = None
ratio: Ratio | None = None
model: Model | Literal['gpt-live-1'] | None = None
const_model: ConstModel | Literal['gpt-live-1'] | None = None
direct: Literal['abc'] | None = None
number: Literal[5] | None = None
codes: list[Literal['abc']] | None = None
code: Code | None = None
level: Level | None = None
unmet: Annotated[Literal['abc'] | None, Field(max_length=2)] = None
ratios: list[Ratio1] | None = None
patterned: list[Literal['abc']] | None = None
# generated by datamodel-codegen:
# filename: redundant_constraints.json
from __future__ import annotations
from enum import Enum
from typing import Annotated, Literal
from pydantic import (
BaseModel,
Field,
NegativeInt,
NonNegativeInt,
PositiveFloat,
RootModel,
)
class Count(RootModel[NonNegativeInt | None]):
root: Annotated[NonNegativeInt | None, Field(ge=0)]
class Model(RootModel[str]):
root: Annotated[str, Field(min_length=1)]
class Model1(RootModel[Literal['gpt-live-1']]):
root: Annotated[Literal['gpt-live-1'], Field(min_length=1)]
class ConstModel(RootModel[str]):
root: Annotated[str, Field(min_length=1)]
class ConstModel1(RootModel[Literal['gpt-live-1']]):
root: Annotated[Literal['gpt-live-1'], Field(min_length=1)]
class Code(RootModel[Literal['abc']]):
root: Annotated[Literal['abc'], Field(min_length=2)]
class Ratio1(RootModel[float]):
root: Annotated[float, Field(ge=1.0)]
class PatternedItem(RootModel[Literal['abc']]):
root: Annotated[Literal['abc'], Field(min_length=1, pattern='^a')]
class CountModel(RootModel[NonNegativeInt]):
root: Annotated[NonNegativeInt, Field(ge=0)]
class NullableCount(RootModel[NonNegativeInt | None]):
root: Annotated[NonNegativeInt | None, Field(ge=0)]
class Bounded(RootModel[NonNegativeInt]):
root: Annotated[NonNegativeInt, Field(ge=0, le=9)]
class Ratio(RootModel[PositiveFloat]):
root: Annotated[PositiveFloat, Field(gt=0)]
class ModelIds1(RootModel[str]):
root: Annotated[str, Field(min_length=1)]
class ModelIds(RootModel[ModelIds1 | Literal['gpt-live-1']]):
root: ModelIds1 | Literal['gpt-live-1']
class ConstIds1(RootModel[str]):
root: Annotated[str, Field(min_length=1)]
class ConstIds(RootModel[ConstIds1 | Literal['gpt-live-1']]):
root: ConstIds1 | Literal['gpt-live-1']
class CodeModel(RootModel[Literal['abc']]):
root: Annotated[Literal['abc'], Field(min_length=1)]
class Level(Enum):
bb = 'bb'
ccc = 'ccc'
class RedundantConstraints(BaseModel):
count: Annotated[NonNegativeInt | None, Field(ge=0)] = None
plain: NonNegativeInt | None = None
negative: Annotated[NegativeInt | None, Field(lt=0)] = None
positive: Annotated[PositiveFloat | None, Field(gt=0)] = None
both: Annotated[NonNegativeInt | None, Field(ge=0, le=10)] = None
counts: list[Count | None] | None = None
root_count: CountModel | None = None
nullable_count: NullableCount | None = None
bounded: Bounded | None = None
ratio: Ratio | None = None
model: Model | Model1 | None = None
const_model: ConstModel | ConstModel1 | None = None
direct: Annotated[Literal['abc'] | None, Field(min_length=1)] = None
number: Annotated[Literal[5] | None, Field(ge=1)] = None
codes: list[Code] | None = None
code: CodeModel | None = None
level: Level | None = None
unmet: Annotated[Literal['abc'] | None, Field(max_length=2)] = None
ratios: list[Ratio1] | None = None
patterned: list[PatternedItem] | None = None
--original-field-name-delimiter¶
Specify delimiter for original field names when using snake-case conversion.
The --original-field-name-delimiter option works with --snake-case-field to specify
the delimiter used in original field names. This is useful when field names contain
delimiters like spaces or hyphens that should be treated as word boundaries during
snake_case conversion.
Option relationships:
- Requires:
--snake-case-fieldenabled ---original-field-name-delimitercan not be used without--snake-case-field.
Usage
datamodel-codegen --input space_field_enum.json --snake-case-field --original-field-name-delimiter " " # (1)!
-
--original-field-name-delimiter- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"SpaceIF": {
"$ref": "#/definitions/SpaceIF"
}
},
"definitions": {
"SpaceIF": {
"type": "string",
"enum": [
"Space Field"
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: space_field_enum.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field
class SpaceIF(Enum):
space_field = 'Space Field'
class Model(BaseModel):
space_if: SpaceIF | None = Field(None, alias='SpaceIF')
--read-length-keywords-by-type¶
Read the string and the array keywords for their own kind only, as JSON Schema does.
minLength, maxLength and pattern apply to strings and minItems, maxItems and uniqueItems to arrays. Without
this option a declared array writes minLength and maxLength as its item counts (Field(max_length=2) on a list,
which rejects ["a", "b", "c"], valid for the schema) and a declared string minItems and maxItems as its length
(constr(max_length=2), which rejects "abc"). With it such a keyword is left out silently, as minimum beside a
string is: at a property, an item, a map value, a root, the branches of a union and a schema with items but no
type, also where an override writes the field as another type.
Usage
datamodel-codegen --input length_keywords_by_type.json --use-annotated --read-length-keywords-by-type # (1)!
-
--read-length-keywords-by-type- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "LengthKeywordsByType",
"type": "object",
"properties": {
"tags": {"type": "array", "items": {"type": "string"}, "minLength": 1, "maxLength": 2},
"counted": {"type": "array", "items": {"type": "string"}, "maxItems": 3, "maxLength": 2},
"code": {"type": "string", "minItems": 1, "maxItems": 2},
"either": {"type": ["string", "array"], "items": {"type": "integer"}, "maxLength": 2},
"branch": {"maxLength": 3, "anyOf": [{"type": "array", "items": {"type": "integer"}}, {"type": "string"}]},
"untyped": {"items": {"type": "integer"}, "maxLength": 2},
"nested": {"type": "array", "items": {"type": "array", "items": {"type": "integer"}, "maxLength": 1}},
"by_key": {
"type": "object",
"additionalProperties": {"type": "array", "items": {"type": "integer"}, "maxLength": 1}
},
"letters": {"type": "array", "items": {"enum": ["xx", "yy"]}, "maxLength": 2},
"letter_seq": {
"type": "array",
"items": {"enum": ["xx", "yy"]},
"maxLength": 2,
"x-python-type": "Sequence[str]"
},
"as_text": {"type": "array", "items": {"type": "integer"}, "maxLength": 2, "x-python-type": "str"},
"count": {"type": "integer", "format": "int64", "maxLength": 2},
"short": {"$ref": "#/$defs/Short"},
"named": {"$ref": "#/$defs/Name", "minItems": 1}
},
"$defs": {
"Short": {"type": "array", "items": {"type": "integer"}, "maxLength": 2},
"Name": {"type": "string"}
}
}
Output:
# generated by datamodel-codegen:
# filename: length_keywords_by_type.json
from __future__ import annotations
from collections.abc import Sequence
from enum import Enum
from typing import Annotated
from pydantic import BaseModel, Field, RootModel
from typing_extensions import TypeAliasType
EitherString = TypeAliasType("EitherString", Annotated[str, Field(max_length=2)])
class Branch(RootModel[list[int]]):
root: list[int]
class Branch1(RootModel[str]):
root: Annotated[str, Field(max_length=3)]
class NestedItem(RootModel[list[int]]):
root: list[int]
class Letter(Enum):
xx = 'xx'
yy = 'yy'
class LetterSeqEnum(Enum):
xx = 'xx'
yy = 'yy'
class Short(RootModel[list[int]]):
root: list[int]
class Name(RootModel[str]):
root: str
class LengthKeywordsByType(BaseModel):
tags: list[str] | None = None
counted: Annotated[list[str] | None, Field(max_length=3)] = None
code: str | None = None
either: EitherString | list[int] | None = None
branch: Branch | Branch1 | None = None
untyped: list[int] | None = None
nested: list[NestedItem] | None = None
by_key: dict[str, list[int]] | None = None
letters: list[Letter] | None = None
letter_seq: Sequence[LetterSeqEnum] | None = None
as_text: str | None = None
count: int | None = None
short: Short | None = None
named: str | None = None
# generated by datamodel-codegen:
# filename: length_keywords_by_type.json
from __future__ import annotations
from collections.abc import Sequence
from enum import Enum
from typing import Annotated
from pydantic import BaseModel, Field, RootModel
from typing_extensions import TypeAliasType
EitherString = TypeAliasType("EitherString", Annotated[str, Field(max_length=2)])
class Branch(RootModel[list[int]]):
root: Annotated[list[int], Field(max_length=3)]
class Branch1(RootModel[str]):
root: Annotated[str, Field(max_length=3)]
class NestedItem(RootModel[list[int]]):
root: Annotated[list[int], Field(max_length=1)]
class Letter(Enum):
xx = 'xx'
yy = 'yy'
class LetterSeqEnum(Enum):
xx = 'xx'
yy = 'yy'
class Short(RootModel[list[int]]):
root: Annotated[list[int], Field(max_length=2)]
class Name(RootModel[str]):
root: str
class LengthKeywordsByType(BaseModel):
tags: Annotated[list[str] | None, Field(max_length=2, min_length=1)] = None
counted: Annotated[list[str] | None, Field(max_length=3)] = None
code: Annotated[str | None, Field(max_length=2, min_length=1)] = None
either: EitherString | list[int] | None = None
branch: Branch | Branch1 | None = None
untyped: Annotated[list[int] | None, Field(max_length=2)] = None
nested: list[NestedItem] | None = None
by_key: dict[str, list[int]] | None = None
letters: Annotated[list[Letter] | None, Field(max_length=2)] = None
letter_seq: Annotated[Sequence[LetterSeqEnum] | None, Field(max_length=2)] = None
as_text: Annotated[str | None, Field(max_length=2)] = None
count: int | None = None
short: Short | None = None
named: Annotated[str | None, Field(min_length=1)] = None
--read-msgspec-union-bounds-exactly¶
Decide the bounds of the int member of a msgspec union on the bounds the schema writes.
msgspec decodes every JSON integer as the int member of a union that has a float member too, so the int member goes
without its Meta bounds when they would reject an integer the float member accepts. Without this option the float
member's bound is read as the float it is written as, which past 2**53 is another integer: {"type": "number",
"minimum": 1234567890123456700} reads as 1234567890123456768, so Annotated[int, Meta(ge=1234567890123456750)]
keeps its bound and rejects 1234567890123456720, which the number branch accepts. With it the check reads the bounds
the schema writes, exactly (msgspec.Struct output only).
Usage
datamodel-codegen --input union_integer_bounds.json --output-model-type msgspec.Struct --read-msgspec-union-bounds-exactly # (1)!
-
--read-msgspec-union-bounds-exactly- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Model",
"type": "object",
"properties": {
"wide": {
"anyOf": [
{"type": "integer", "minimum": 1234567890123456750},
{"type": "number", "minimum": 1234567890123456700}
]
},
"narrow": {
"anyOf": [
{"type": "integer", "minimum": 1234567890123456769},
{"type": "number", "minimum": 1234567890123456770}
]
},
"small": {
"anyOf": [
{"type": "integer", "minimum": 10},
{"type": "number", "minimum": 5.5}
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: union_integer_bounds.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Annotated, TypeAlias
from msgspec import UNSET, Meta, Struct, UnsetType
Wide: TypeAlias = Annotated[int, Meta(ge=1234567890123456750)]
Wide1: TypeAlias = Annotated[float, Meta(ge=1.2345678901234568e+18)]
Narrow: TypeAlias = Annotated[int, Meta(ge=1234567890123456769)]
Narrow1: TypeAlias = Annotated[float, Meta(ge=1.2345678901234568e+18)]
Small: TypeAlias = Annotated[int, Meta(ge=10)]
Small1: TypeAlias = Annotated[float, Meta(ge=5.5)]
class Model(Struct):
wide: int | Wide1 | UnsetType = UNSET
narrow: Narrow | Narrow1 | UnsetType = UNSET
small: int | Small1 | UnsetType = UNSET
# generated by datamodel-codegen:
# filename: union_integer_bounds.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Annotated, TypeAlias
from msgspec import UNSET, Meta, Struct, UnsetType
Wide: TypeAlias = Annotated[int, Meta(ge=1234567890123456750)]
Wide1: TypeAlias = Annotated[float, Meta(ge=1.2345678901234568e+18)]
Narrow: TypeAlias = Annotated[int, Meta(ge=1234567890123456769)]
Narrow1: TypeAlias = Annotated[float, Meta(ge=1.2345678901234568e+18)]
Small: TypeAlias = Annotated[int, Meta(ge=10)]
Small1: TypeAlias = Annotated[float, Meta(ge=5.5)]
class Model(Struct):
wide: Wide | Wide1 | UnsetType = UNSET
narrow: int | Narrow1 | UnsetType = UNSET
small: int | Small1 | UnsetType = UNSET
--remove-special-field-name-prefix¶
Remove the special prefix from field names.
The --remove-special-field-name-prefix flag configures the code generation behavior.
Usage
-
--remove-special-field-name-prefix- the option documented here
Examples
Input Schema:
{
"$id": "schema_v2.json",
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
"@id": {
"type": "string",
"format": "uri",
"pattern": "^http.*$",
"title": "Id must be presesnt and must be a URI"
},
"@type": { "type": "string" },
"@+!type": { "type": "string" },
"@-!type": { "type": "string" },
"profile": { "type": "string" }
},
"required": ["@id", "@type"]
}
Output:
# generated by datamodel-codegen:
# filename: special_prefix_model.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import AnyUrl, BaseModel, Field
class Model(BaseModel):
id: AnyUrl = Field(..., alias='@id', title='Id must be presesnt and must be a URI')
type: str = Field(..., alias='@type')
type_1: str | None = Field(None, alias='@+!type')
type_2: str | None = Field(None, alias='@-!type')
profile: str | None = None
--serialization-aliases¶
Apply custom Pydantic v2 serialization aliases via inline JSON or a JSON file path.
The --serialization-aliases option lets Pydantic v2 models keep input aliases
or validation aliases while using separate output-only names for serialization.
Usage
datamodel-codegen --input serialization_aliases.json --aliases aliases/serialization_aliases.json --serialization-aliases aliases/serialization_aliases_output.json --output-model-type pydantic_v2.BaseModel # (1)!
-
--serialization-aliases- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Messaging",
"type": "object",
"definitions": {
"SendMessageV2": {
"type": "object",
"properties": {
"textMessage": {
"type": "string"
}
},
"required": ["textMessage"]
},
"OtherMessage": {
"type": "object",
"properties": {
"other-name": {
"type": "string"
}
},
"required": ["other-name"]
},
"SameNameMessage": {
"type": "object",
"properties": {
"same-name": {
"type": "string"
}
},
"required": ["same-name"]
},
"RequiredOnlyMessage": {
"type": "object",
"allOf": [
{
"type": "object",
"properties": {
"known-name": {
"type": "string"
}
},
"required": [
"known-name",
"missing-required",
"plain-missing",
"allof-unmapped"
]
}
],
"required": [
"known-name",
"missing-required",
"plain-missing",
"allof-unmapped"
]
},
"RequiredOnlyGrandBase": {
"type": "object",
"properties": {
"grand-name": {
"type": "integer"
},
"bare-name": {}
},
"required": ["grand-name", "bare-name"]
},
"RequiredOnlyBase": {
"type": "object",
"properties": {
"base-name": {
"type": "string"
}
},
"allOf": [
{
"$ref": "#/definitions/RequiredOnlyGrandBase"
}
],
"required": ["base-name"]
},
"RequiredOnlyRefMessage": {
"type": "object",
"properties": {
"own-name": {
"type": "string"
}
},
"allOf": [
{
"$ref": "#/definitions/RequiredOnlyBase"
}
],
"required": [
"own-name",
"grand-name",
"bare-name",
"ignored-missing",
"ref-missing-required",
"ref-plain-missing"
]
},
"RequiredOnlyEmptyAllOfBase": {
"type": "object",
"allOf": [
{
"type": "object"
}
]
},
"RequiredOnlyEmptyAllOfMessage": {
"type": "object",
"allOf": [
{
"$ref": "#/definitions/RequiredOnlyEmptyAllOfBase"
}
],
"required": ["empty-missing"]
},
"RequiredOnlyRecursiveEmptyGrandBase": {
"type": "object",
"properties": {
"unrelated-name": {
"type": "string"
}
}
},
"RequiredOnlyRecursiveEmptyBase": {
"type": "object",
"allOf": [
{
"$ref": "#/definitions/RequiredOnlyRecursiveEmptyGrandBase"
}
]
},
"RequiredOnlyRecursiveEmptyMessage": {
"type": "object",
"allOf": [
{
"$ref": "#/definitions/RequiredOnlyRecursiveEmptyBase"
}
],
"required": ["recursive-missing"]
}
},
"properties": {
"send": {
"$ref": "#/definitions/SendMessageV2"
},
"other": {
"$ref": "#/definitions/OtherMessage"
},
"same": {
"$ref": "#/definitions/SameNameMessage"
},
"requiredOnly": {
"$ref": "#/definitions/RequiredOnlyMessage"
},
"requiredOnlyRef": {
"$ref": "#/definitions/RequiredOnlyRefMessage"
},
"requiredOnlyEmptyAllOf": {
"$ref": "#/definitions/RequiredOnlyEmptyAllOfMessage"
},
"requiredOnlyRecursiveEmpty": {
"$ref": "#/definitions/RequiredOnlyRecursiveEmptyMessage"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: serialization_aliases.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import AliasChoices, BaseModel, Field
class SendMessageV2(BaseModel):
message: str = Field(
...,
serialization_alias='messageText',
validation_alias=AliasChoices('textMessage', 'message', 'text'),
)
class OtherMessage(BaseModel):
other_name: str = Field(..., alias='other-name', serialization_alias='otherName')
class SameNameMessage(BaseModel):
same_name: str = Field(..., alias='same-name', serialization_alias='same_name')
class RequiredOnlyMessage(BaseModel):
known_name: str = Field(..., alias='known-name')
missingRequiredInput: Any = Field(
...,
serialization_alias='missingRequired',
validation_alias=AliasChoices('missing-required', 'missingRequiredInput'),
)
plainMissingInput: Any = Field(
..., alias='plain-missing', serialization_alias='plainMissing'
)
allof_unmapped: Any = Field(..., alias='allof-unmapped')
class RequiredOnlyGrandBase(BaseModel):
grand_name: int = Field(..., alias='grand-name')
bare_name: Any = Field(..., alias='bare-name')
class RequiredOnlyBase(RequiredOnlyGrandBase):
base_name: str = Field(..., alias='base-name')
class RequiredOnlyRefMessage(RequiredOnlyBase):
own_name: str = Field(..., alias='own-name')
grand_name: int = Field(
...,
serialization_alias='grandName',
validation_alias=AliasChoices('grand-name', 'grandInput'),
)
bare_name: Any = Field(..., alias='bare-name', serialization_alias='bareName')
ignored_missing: Any = Field(..., alias='ignored-missing')
refMissingInput: Any = Field(
...,
serialization_alias='refMissingRequired',
validation_alias=AliasChoices('ref-missing-required', 'refMissingInput'),
)
refPlainMissingInput: Any = Field(
..., alias='ref-plain-missing', serialization_alias='refPlainMissing'
)
class RequiredOnlyEmptyAllOfBase(BaseModel):
pass
class RequiredOnlyEmptyAllOfMessage(RequiredOnlyEmptyAllOfBase):
emptyMissingInput: Any = Field(
...,
serialization_alias='emptyMissing',
validation_alias=AliasChoices('empty-missing', 'emptyMissingInput'),
)
class RequiredOnlyRecursiveEmptyGrandBase(BaseModel):
unrelated_name: str | None = Field(None, alias='unrelated-name')
class RequiredOnlyRecursiveEmptyBase(RequiredOnlyRecursiveEmptyGrandBase):
pass
class RequiredOnlyRecursiveEmptyMessage(RequiredOnlyRecursiveEmptyBase):
recursiveMissingInput: Any = Field(
..., alias='recursive-missing', serialization_alias='recursiveMissing'
)
class Messaging(BaseModel):
send: SendMessageV2 | None = None
other: OtherMessage | None = None
same: SameNameMessage | None = None
requiredOnly: RequiredOnlyMessage | None = None
requiredOnlyRef: RequiredOnlyRefMessage | None = None
requiredOnlyEmptyAllOf: RequiredOnlyEmptyAllOfMessage | None = None
requiredOnlyRecursiveEmpty: RequiredOnlyRecursiveEmptyMessage | None = None
--set-default-enum-member¶
Use the legacy flag for deserializing enum defaults.
The --set-default-enum-member flag is deprecated. Use --deserialize-default-values enum instead.
Deprecated: --set-default-enum-member is deprecated. Use --deserialize-default-values enum instead.
Usage
-
--set-default-enum-member- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "User",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"animal": {
"type": "string",
"enum": [
"dog",
"cat",
"snake"
],
"default": "dog"
},
"pet": {
"type": "string",
"enum": [
"dog",
"cat",
"snake"
],
"default": "cat"
},
"redistribute": {
"type": "array",
"items": {
"type": "string",
"enum": [
"static",
"connected"
]
}
}
},
"definitions": {
"redistribute": {
"type": "array",
"items": {
"type": "string",
"enum": [
"static",
"connected"
]
},
"description": "Redistribute type for routes."
}
}
}
Output:
# generated by datamodel-codegen:
# filename: duplicate_enum.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field, RootModel
class Animal(Enum):
dog = 'dog'
cat = 'cat'
snake = 'snake'
class RedistributeEnum(Enum):
static = 'static'
connected = 'connected'
class User(BaseModel):
name: str | None = None
animal: Animal | None = Animal.dog
pet: Animal | None = Animal.cat
redistribute: list[RedistributeEnum] | None = None
class Redistribute(RootModel[list[RedistributeEnum]]):
root: list[RedistributeEnum] = Field(
..., description='Redistribute type for routes.'
)
--snake-case-field¶
Convert field names to snake_case format.
The --snake-case-field flag converts camelCase or PascalCase field names
to snake_case format in the generated Python code, following Python naming
conventions (PEP 8).
Related: --capitalize-enum-members
Usage
-
--snake-case-field- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "InvalidEnum",
"type": "string",
"enum": [
"1 value",
" space",
"*- special",
"schema",
"MRO",
"mro"
]
}
Output:
# generated by datamodel-codegen:
# filename: invalid_enum_name.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
class InvalidEnum(Enum):
field_1_value = '1 value'
field_space = ' space'
field___special = '*- special'
schema = 'schema'
mro_1 = 'MRO'
mro_ = 'mro'
--special-field-name-prefix¶
Prefix to add to special field names (like reserved keywords).
The --special-field-name-prefix flag configures the code generation behavior.
Usage
-
--special-field-name-prefix- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "string",
"enum": [
true,
false,
"",
"\n",
"\r\n",
"\t",
"\\x08",
null,
"\\"
]
}
Output:
# generated by datamodel-codegen:
# filename: special_enum.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import RootModel
class ModelEnum(Enum):
True_ = True
False_ = False
special_ = ''
special__1 = '\n'
special__ = '\r\n'
special__2 = '\t'
special_x08 = '\\x08'
special__3 = '\\'
class Model(RootModel[ModelEnum | None]):
root: ModelEnum | None = None
--use-attribute-docstrings¶
Generate field descriptions as attribute docstrings instead of Field descriptions.
The --use-attribute-docstrings flag places field descriptions in Python docstring
format (PEP 224 attribute docstrings) rather than in Field(..., description=...).
This provides better IDE support for hovering over attributes. Requires
--use-field-description to be enabled.
Related: --use-field-description
Usage
datamodel-codegen --input use_attribute_docstrings_test.json --output-model-type pydantic_v2.BaseModel --use-field-description --use-attribute-docstrings # (1)!
-
--use-attribute-docstrings- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Person",
"properties": {
"name": {
"type": "string",
"description": "The person's full name"
},
"age": {
"type": "integer",
"description": "The person's age in years"
}
},
"required": ["name"]
}
Output:
# generated by datamodel-codegen:
# filename: use_attribute_docstrings_test.json
# timestamp: 1985-10-26T08:21:00+00:00
from __future__ import annotations
from pydantic import BaseModel, ConfigDict
class Person(BaseModel):
model_config = ConfigDict(
use_attribute_docstrings=True,
)
name: str
"""
The person's full name
"""
age: int | None = None
"""
The person's age in years
"""
--use-enum-values-in-discriminator¶
Use enum values in discriminator mappings for union types.
The --use-enum-values-in-discriminator flag configures the code generation behavior.
Usage
datamodel-codegen --input discriminator_enum.yaml --use-enum-values-in-discriminator --output-model-type pydantic_v2.BaseModel # (1)!
-
--use-enum-values-in-discriminator- the option documented here
Examples
Input Schema:
openapi: "3.0.0"
components:
schemas:
Request:
oneOf:
- $ref: '#/components/schemas/RequestV1'
- $ref: '#/components/schemas/RequestV2'
discriminator:
propertyName: version
mapping:
v1: '#/components/schemas/RequestV1'
v2: '#/components/schemas/RequestV2'
RequestVersionEnum:
type: string
description: this is not included!
title: no title!
enum:
- v1
- v2
RequestBase:
properties:
version:
$ref: '#/components/schemas/RequestVersionEnum'
required:
- version
RequestV1:
allOf:
- $ref: '#/components/schemas/RequestBase'
properties:
request_id:
type: string
title: test title
description: there is description
required:
- request_id
RequestV2:
allOf:
- $ref: '#/components/schemas/RequestBase'
Output:
# generated by datamodel-codegen:
# filename: discriminator_enum.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 RequestVersionEnum(Enum):
v1 = 'v1'
v2 = 'v2'
class RequestBase(BaseModel):
version: RequestVersionEnum
class RequestV1(RequestBase):
request_id: str = Field(..., description='there is description', title='test title')
version: Literal[RequestVersionEnum.v1, 'v1']
class RequestV2(RequestBase):
version: Literal[RequestVersionEnum.v2, 'v2']
class Request(RootModel[RequestV1 | RequestV2]):
root: RequestV1 | RequestV2 = Field(..., discriminator='version')
--use-field-description¶
Include schema descriptions as Field docstrings.
The --use-field-description flag extracts the description property from
schema fields and includes them as docstrings or Field descriptions in the
generated models, preserving documentation from the original schema.
Related: --use-inline-field-description, --use-schema-description
Usage
-
--use-field-description- 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
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
default: 1
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Users:
type: array
items:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Id:
type: string
Rules:
type: array
items:
type: string
Error:
description: "error result.\nNow with multi-line docstrings."
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.\nNow also with multi-line docstrings."
apiVersionNumber:
type: string
description: To be used as a version parameter value
apiUrl:
type: string
format: uri
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
description: Event object
properties:
name:
type: string
Result:
type: object
properties:
event:
$ref: '#/components/schemas/Event'
Output:
# generated by datamodel-codegen:
# filename: api_multiline_docstrings.yaml
# timestamp: 2022-11-11T00:00:00+00:00
from __future__ import annotations
from pydantic import AnyUrl, BaseModel, RootModel
class Pet(BaseModel):
id: int
name: str
tag: str | None = None
class Pets(RootModel[list[Pet]]):
root: list[Pet]
class User(BaseModel):
id: int
name: str
tag: str | None = 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: str | None = None
"""
To be used as a dataset parameter value.
Now also with multi-line docstrings.
"""
apiVersionNumber: str | None = None
"""
To be used as a version parameter value
"""
apiUrl: AnyUrl | None = None
"""
The URL describing the dataset's fields
"""
apiDocumentationUrl: AnyUrl | None = None
"""
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
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(..., title='MyAnnotatedType')]
)
"""
An annotated union type
"""
class ModelWithTypeAliasField(BaseModel):
simple_field: SimpleString | None = None
union_field: UnionType | None = None
array_field: ArrayType | None = None
annotated_field: AnnotatedType | None = None
--use-field-description-example¶
Add field examples to docstrings.
The --use-field-description-example flag adds the example or examples
property from schema fields as docstrings. This provides documentation that
is visible in IDE intellisense.
Related: --use-field-description, --use-inline-field-description
Usage
-
--use-field-description-example- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Extras",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "normal key",
"key1": 123,
"key2": 456,
"$exclude": 123,
"invalid-key-1": "abc",
"-invalid+key_2": "efg",
"$comment": "comment",
"$id": "#name",
"register": "hij",
"schema": "klm",
"x-repr": true,
"x-abc": true,
"example": "example",
"readOnly": true
},
"age": {
"type": "integer",
"example": 12,
"writeOnly": true,
"examples": [
13,
20
]
},
"status": {
"type": "string",
"examples": [
"active"
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: extras.json
# timestamp: 2022-11-11T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class Extras(BaseModel):
name: str | None = Field(None, description='normal key', examples=['example'])
"""
Example: 'example'
"""
age: int | None = Field(None, examples=[13, 20], json_schema_extra={'example': 12})
"""
Examples:
- 13
- 20
"""
status: str | None = Field(None, examples=['active'])
"""
Example: 'active'
"""
--use-inline-field-description¶
Add field descriptions as inline comments.
The --use-inline-field-description flag adds the description property from
schema fields as inline comments after each field definition. This provides
documentation without using Field() wrappers.
Related: --use-field-description, --use-schema-description
Usage
-
--use-inline-field-description- 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
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
default: 1
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Users:
type: array
items:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Id:
type: string
Rules:
type: array
items:
type: string
Error:
description: "error result.\nNow with multi-line docstrings."
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.\nNow also with multi-line docstrings."
apiVersionNumber:
type: string
description: To be used as a version parameter value
apiUrl:
type: string
format: uri
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
description: Event object
properties:
name:
type: string
Result:
type: object
properties:
event:
$ref: '#/components/schemas/Event'
Output:
# generated by datamodel-codegen:
# filename: api_multiline_docstrings.yaml
# timestamp: 2022-11-11T00:00:00+00:00
from __future__ import annotations
from pydantic import AnyUrl, BaseModel, Field, RootModel
class Pet(BaseModel):
id: int
name: str
tag: str | None = None
class Pets(RootModel[list[Pet]]):
root: list[Pet]
class User(BaseModel):
id: int
name: str
tag: str | None = 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: str | None = Field(
None,
description='To be used as a dataset parameter value.\nNow also with multi-line docstrings.',
)
"""
To be used as a dataset parameter value.
Now also with multi-line docstrings.
"""
apiVersionNumber: str | None = Field(
None, description='To be used as a version parameter value'
)
"""To be used as a version parameter value"""
apiUrl: AnyUrl | None = Field(
None, description="The URL describing the dataset's fields"
)
"""The URL describing the dataset's fields"""
apiDocumentationUrl: AnyUrl | None = Field(
None, description='A URL to the API console for each API'
)
"""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
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "MultilineDescriptionWithExample",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "User name.\nThis is a multi-line description.",
"example": "John Doe"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: multiline_description_with_example.json
# timestamp: 2022-11-11T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class MultilineDescriptionWithExample(BaseModel):
name: str | None = Field(
None,
description='User name.\nThis is a multi-line description.',
examples=['John Doe'],
)
"""
User name.
This is a multi-line description.
Example: 'John Doe'
"""
--use-one-model-per-ref-site¶
Give an object $ref with sibling keywords one model per place it is written.
A $ref beside other keywords is parsed as its target merged with them. Without this option the merged object is
parsed at the path that reaches it, and the copy of each such $ref its target holds is parsed again below it, so a
chain of N definitions whose next is a $ref to the next one beside required gives N(N-1)/2 site models (Next,
Next1, ..., where the copies of one place, such as Next1 and Next4, validate the same documents), one nested
parse per hop, which stops with "Schema nesting is too deep" for a long chain. With it each place such a $ref is
written, with the $dynamicAnchor bindings of its dynamic scope, gets one model, which every unchanged copy of the
place shares, parsed from a worklist without nesting: N-1 site models beside the N definitions. The field that holds
the $ref keeps its own required, default and alias. Where --read-only-write-only-model-type request-response
splits the models, the model of a place is parsed where it is first met, so a chain still nests one parse per hop.
Usage
-
--use-one-model-per-ref-site- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Chain",
"$ref": "#/$defs/Link0",
"$defs": {
"Link0": {
"type": "object",
"properties": {
"v": {
"type": "integer"
},
"next": {
"$ref": "#/$defs/Link1",
"required": [
"v"
],
"description": "link 0"
}
}
},
"Link1": {
"type": "object",
"properties": {
"v": {
"type": "integer"
},
"next": {
"$ref": "#/$defs/Link2",
"required": [
"v"
],
"description": "link 1"
}
}
},
"Link2": {
"type": "object",
"properties": {
"v": {
"type": "integer"
},
"next": {
"$ref": "#/$defs/Link3",
"required": [
"v"
],
"description": "link 2"
}
}
},
"Link3": {
"type": "object",
"properties": {
"v": {
"type": "integer"
},
"next": {
"$ref": "#/$defs/Link4",
"required": [
"v"
],
"description": "link 3"
}
}
},
"Link4": {
"type": "object",
"properties": {
"v": {
"type": "integer"
}
}
}
}
}
Output:
# generated by datamodel-codegen:
# filename: ref_site_chain.json
from __future__ import annotations
from pydantic import BaseModel, Field, RootModel
class Next3(BaseModel):
v: int
class Link3(BaseModel):
v: int | None = None
next: Next3 | None = Field(None, description='link 3')
class Link4(BaseModel):
v: int | None = None
class Next2(BaseModel):
v: int
next: Next3 | None = Field(None, description='link 3')
class Link2(BaseModel):
v: int | None = None
next: Next2 | None = Field(None, description='link 2')
class Next1(BaseModel):
v: int
next: Next2 | None = Field(None, description='link 2')
class Link1(BaseModel):
v: int | None = None
next: Next1 | None = Field(None, description='link 1')
class Next(BaseModel):
v: int
next: Next1 | None = Field(None, description='link 1')
class Link0(BaseModel):
v: int | None = None
next: Next | None = Field(None, description='link 0')
class Chain(RootModel[Link0]):
root: Link0 = Field(..., title='Chain')
# generated by datamodel-codegen:
# filename: ref_site_chain.json
from __future__ import annotations
from pydantic import BaseModel, Field, RootModel
class Next3(BaseModel):
v: int
class Next2(BaseModel):
v: int
next: Next3 | None = Field(None, description='link 3')
class Next1(BaseModel):
v: int
next: Next2 | None = Field(None, description='link 2')
class Next(BaseModel):
v: int
next: Next1 | None = Field(None, description='link 1')
class Link0(BaseModel):
v: int | None = None
next: Next | None = Field(None, description='link 0')
class Next6(BaseModel):
v: int
class Next5(BaseModel):
v: int
next: Next6 | None = Field(None, description='link 3')
class Next4(BaseModel):
v: int
next: Next5 | None = Field(None, description='link 2')
class Link1(BaseModel):
v: int | None = None
next: Next4 | None = Field(None, description='link 1')
class Next8(BaseModel):
v: int
class Next7(BaseModel):
v: int
next: Next8 | None = Field(None, description='link 3')
class Link2(BaseModel):
v: int | None = None
next: Next7 | None = Field(None, description='link 2')
class Next9(BaseModel):
v: int
class Link3(BaseModel):
v: int | None = None
next: Next9 | None = Field(None, description='link 3')
class Link4(BaseModel):
v: int | None = None
class Chain(RootModel[Link0]):
root: Link0 = Field(..., title='Chain')
--use-schema-description¶
Use schema description as class docstring.
The --use-schema-description flag extracts the description property from
schema definitions and adds it as a docstring to the generated class. This is
useful for preserving documentation from your schema in the generated code.
Related: --use-field-description, --use-inline-field-description
Usage
-
--use-schema-description- 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
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
default: 1
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Users:
type: array
items:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Id:
type: string
Rules:
type: array
items:
type: string
Error:
description: "error result.\nNow with multi-line docstrings."
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.\nNow also with multi-line docstrings."
apiVersionNumber:
type: string
description: To be used as a version parameter value
apiUrl:
type: string
format: uri
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
description: Event object
properties:
name:
type: string
Result:
type: object
properties:
event:
$ref: '#/components/schemas/Event'
Output:
# generated by datamodel-codegen:
# filename: api_multiline_docstrings.yaml
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import AnyUrl, BaseModel, Field, RootModel
class Pet(BaseModel):
id: int
name: str
tag: str | None = None
class Pets(RootModel[list[Pet]]):
root: list[Pet]
class User(BaseModel):
id: int
name: str
tag: str | None = 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):
"""
error result.
Now with multi-line docstrings.
"""
code: int
message: str
class Api(BaseModel):
apiKey: str | None = Field(
None,
description='To be used as a dataset parameter value.\nNow also with multi-line docstrings.',
)
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):
"""
Event object
"""
name: str | None = None
class Result(BaseModel):
event: Event | None = None
--use-serialization-alias¶
Use serialization_alias instead of alias for field aliasing (Pydantic v2 only).
The --use-serialization-alias flag changes field aliasing to use serialization_alias
instead of alias. This allows setting values using the Pythonic field name while
serializing to the original JSON property name.
Usage
datamodel-codegen --input no_alias.json --use-serialization-alias --output-model-type pydantic_v2.BaseModel # (1)!
-
--use-serialization-alias- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"first-name": {
"type": "string"
},
"last-name": {
"type": "string"
},
"email_address": {
"type": "string"
}
},
"required": ["first-name", "last-name"]
}
Output:
# generated by datamodel-codegen:
# filename: no_alias.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class Person(BaseModel):
first_name: str = Field(..., serialization_alias='first-name')
last_name: str = Field(..., serialization_alias='last-name')
email_address: str | None = None
# generated by datamodel-codegen:
# filename: no_alias.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from pydantic import BaseModel, Field
class Person(BaseModel):
first_name: str = Field(..., alias='first-name')
last_name: str = Field(..., alias='last-name')
email_address: str | None = None
--use-single-line-docstring¶
Emit short docstrings on a single line.
The --use-single-line-docstring flag formats docstrings that fit on one line
as compact single-line docstrings while keeping the historical multi-line
format as the default.
Related: --use-field-description, --use-schema-description
Usage
-
--use-single-line-docstring- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": ["string", "null"],
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
},
"friends": {
"type": "array"
},
"comment": {
"type": "null"
}
}
}
Output:
# generated by datamodel-codegen:
# filename: person.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field, conint
class Person(BaseModel):
firstName: str | None = None
"""The person's first name."""
lastName: str | None = None
"""The person's last name."""
age: conint(ge=0) | None = None
"""Age in years which must be equal to or greater than zero."""
friends: list[Any] | None = None
comment: None = Field(None)
--use-site-models-for-constrained-refs¶
Give an allOf of $ref members whose other parts add assertions its own model.
Without the option such an allOf is written as the referenced type, which leaves out the constraints, the enum values
or the type its other parts add: allOf: [{$ref: Quantity}], maximum: 10 accepts 11. With the option the site gets
its own model of the values all parts admit (conint(ge=1, le=10)), named after the site, and an allOf of enum
references gets an enum of the members they share. The referenced type stays where it enforces what the parts enforce
together in the output (dataclasses and TypedDict check no constraints, so only types and literals count there), and
msgspec writes the added constraints beside the reference where its Meta takes them. A model-level
--type-overrides entry of the referenced model applies to its site models too.
Usage
datamodel-codegen --input site_models_for_constrained_refs.json --use-site-models-for-constrained-refs # (1)!
-
--use-site-models-for-constrained-refs- the option documented here
Examples
Input Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Order",
"type": "object",
"properties": {
"quantity": {
"allOf": [
{
"$ref": "#/$defs/Quantity"
}
],
"maximum": 10
},
"sizes": {
"type": "array",
"items": {
"allOf": [
{
"$ref": "#/$defs/Size"
},
{
"enum": [
"m",
"l"
]
}
]
}
}
},
"$defs": {
"Quantity": {
"type": "integer",
"minimum": 1
},
"Size": {
"type": "string",
"enum": [
"s",
"m",
"l"
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: site_models_for_constrained_refs.json
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, RootModel, conint
class Quantity1(RootModel[conint(ge=1, le=10)]):
root: conint(ge=1, le=10)
class Size2(Enum):
m = 'm'
l = 'l'
class Order(BaseModel):
quantity: Quantity1 | None = None
sizes: list[Size2] | None = None
class Quantity(RootModel[conint(ge=1)]):
root: conint(ge=1)
class Size(Enum):
s = 's'
m = 'm'
l = 'l'
# generated by datamodel-codegen:
# filename: site_models_for_constrained_refs.json
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, RootModel, conint
class Quantity(RootModel[conint(ge=1)]):
root: conint(ge=1)
class Size(Enum):
s = 's'
m = 'm'
l = 'l'
class Order(BaseModel):
quantity: Quantity | None = None
sizes: list[Size] | None = None
--use-tag-as-union-variant-name¶
Name inline oneOf/anyOf branch models after their tag: what --infer-union-variant-names does, skipping tags whose class names collide, plus single-branch unions (type: "exec" -> LocalShellActionExec) and single-key branches ({"granular": ...} -> AskForApprovalGranular).
--infer-union-variant-names needs at least two branches with distinct literals
on one field, so a union with one tagged branch keeps a position-based name that
changes once a second branch is added, and a branch tagged by its only key, as in
externally tagged enums, is never named. --use-tag-as-union-variant-name gives
the names --infer-union-variant-names gives wherever that option names a union
with distinct class names, and in the other unions also names:
- the branches after a literal field that only one branch carries or that the key
branches below lack, picked like
--infer-union-variant-namespicks it (thediscriminatorproperty first, then property order) except that a field the union schema itself fixes to a single literal is skipped; a branch that is a union itself is not named this way; - a key branch after its key: its only own property (one the union schema does
not declare), required and not a single literal, when the branch has no
oneOf/anyOfand noallOfof its own that adds properties (the union schema'sallOfis shared by every branch), and fixes no field the union declares without a literal to a single literal, unless the union is one branch besidenull.
String enum branches and branches with several untagged properties keep
position-based names. Names are compared as the class names they become, so
foo-bar and fooBar (both FooBar) collide: a literal field whose names
collide is skipped for the next one, and literal names win over key names, so a
key name that collides with a literal name or another key name is dropped and
its branch keeps a position-based name.
Under --naming-strategy parent-prefixed or full-path, a model in the value
of a branch named after its key is named as if the branch were not in its path,
so the key is not repeated: the branch ItemEditedChangesFieldValue holds
ItemEditedFieldValue, not ItemEditedChangesFieldValueFieldValue, numbered
like any other name when another model has it.
| Branches | default | --infer-union-variant-names |
--use-tag-as-union-variant-name |
|---|---|---|---|
Several branches, distinct type literals |
Pet1, Pet2 |
PetCat, PetDog |
PetCat, PetDog |
Single branch (type: "exec") |
LocalShellAction1 |
LocalShellAction1 |
LocalShellActionExec |
Single-key branch ({"granular": ...}) |
AskForApproval2 |
AskForApproval2 |
AskForApprovalGranular |
Related: --infer-union-variant-names, --use-title-as-name
Usage
-
--use-tag-as-union-variant-name- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Session",
"type": "object",
"required": ["pet", "action", "approval"],
"properties": {
"pet": {"$ref": "#/definitions/Pet"},
"action": {"$ref": "#/definitions/LocalShellAction"},
"approval": {"$ref": "#/definitions/AskForApproval"}
},
"definitions": {
"Pet": {
"oneOf": [
{
"type": "object",
"required": ["type", "meows"],
"properties": {
"type": {"const": "cat"},
"meows": {"type": "boolean"}
}
},
{
"type": "object",
"required": ["type", "barks"],
"properties": {
"type": {"const": "dog"},
"barks": {"type": "boolean"}
}
}
]
},
"LocalShellAction": {
"oneOf": [
{
"type": "object",
"required": ["command", "type"],
"properties": {
"command": {"type": "array", "items": {"type": "string"}},
"type": {"type": "string", "enum": ["exec"]}
}
}
]
},
"AskForApproval": {
"oneOf": [
{"type": "string", "enum": ["untrusted", "never"]},
{
"type": "object",
"additionalProperties": false,
"required": ["granular"],
"properties": {
"granular": {
"type": "object",
"required": ["sandbox"],
"properties": {
"sandbox": {"type": "boolean"}
}
}
}
}
]
}
}
}
Output:
# generated by datamodel-codegen:
# filename: use_tag_as_union_variant_name.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, ConfigDict, RootModel
class PetCat(BaseModel):
type: Literal['cat']
meows: bool
class PetDog(BaseModel):
type: Literal['dog']
barks: bool
class Pet(RootModel[PetCat | PetDog]):
root: PetCat | PetDog
class Type(Enum):
exec = 'exec'
class LocalShellActionExec(BaseModel):
command: list[str]
type: Type
class LocalShellAction(RootModel[LocalShellActionExec]):
root: LocalShellActionExec
class AskForApproval1(Enum):
untrusted = 'untrusted'
never = 'never'
class Granular(BaseModel):
sandbox: bool
class AskForApprovalGranular(BaseModel):
model_config = ConfigDict(
extra='forbid',
)
granular: Granular
class AskForApproval(RootModel[AskForApproval1 | AskForApprovalGranular]):
root: AskForApproval1 | AskForApprovalGranular
class Session(BaseModel):
pet: Pet
action: LocalShellAction
approval: AskForApproval
# generated by datamodel-codegen:
# filename: use_tag_as_union_variant_name.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, ConfigDict, RootModel
class Pet1(BaseModel):
type: Literal['cat']
meows: bool
class Pet2(BaseModel):
type: Literal['dog']
barks: bool
class Pet(RootModel[Pet1 | Pet2]):
root: Pet1 | Pet2
class Type(Enum):
exec = 'exec'
class LocalShellAction1(BaseModel):
command: list[str]
type: Type
class LocalShellAction(RootModel[LocalShellAction1]):
root: LocalShellAction1
class AskForApproval1(Enum):
untrusted = 'untrusted'
never = 'never'
class Granular(BaseModel):
sandbox: bool
class AskForApproval2(BaseModel):
model_config = ConfigDict(
extra='forbid',
)
granular: Granular
class AskForApproval(RootModel[AskForApproval1 | AskForApproval2]):
root: AskForApproval1 | AskForApproval2
class Session(BaseModel):
pet: Pet
action: LocalShellAction
approval: AskForApproval
--use-title-as-name¶
Use schema title as the generated class name.
The --use-title-as-name flag uses the title property from the schema
as the class name instead of deriving it from the property name or path.
This is useful when schemas have descriptive titles that should be preserved.
Related: --class-name
Usage
-
--use-title-as-name- the option documented here
Examples
Input Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ProcessingStatus": {
"title": "Processing Status Title",
"enum": [
"COMPLETED",
"PENDING",
"FAILED"
],
"type": "string",
"description": "The processing status"
},
"kind": {
"type": "string"
},
"ExtendedProcessingTask": {
"title": "Extended Processing Task Title",
"oneOf": [
{
"$ref": "#"
},
{
"type": "object",
"title": "NestedCommentTitle",
"properties": {
"comment": {
"type": "string"
}
}
}
]
},
"ExtendedProcessingTasks": {
"title": "Extended Processing Tasks Title",
"type": "array",
"items": [
{
"$ref": "#/definitions/ExtendedProcessingTask"
}
]
},
"ProcessingTask": {
"title": "Processing Task Title",
"type": "object",
"properties": {
"processing_status_union": {
"title": "Processing Status Union Title",
"oneOf": [
{
"title": "Processing Status Detail",
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"description": {
"type": "string"
}
}
},
{
"$ref": "#/definitions/ExtendedProcessingTask"
},
{
"$ref": "#/definitions/ProcessingStatus"
}
],
"default": "COMPLETED"
},
"processing_status": {
"$ref": "#/definitions/ProcessingStatus",
"default": "COMPLETED"
},
"name": {
"type": "string"
},
"kind": {
"$ref": "#/definitions/kind"
}
}
}
},
"title": "Processing Tasks Title",
"type": "array",
"items": [
{
"$ref": "#/definitions/ProcessingTask"
}
]
}
Output:
# generated by datamodel-codegen:
# filename: titles.json
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from enum import Enum
from pydantic import BaseModel, Field, RootModel
class ProcessingStatusTitle(Enum):
COMPLETED = 'COMPLETED'
PENDING = 'PENDING'
FAILED = 'FAILED'
class Kind(RootModel[str]):
root: str
class NestedCommentTitle(BaseModel):
comment: str | None = None
class ProcessingStatusDetail(BaseModel):
id: int | None = None
description: str | None = None
class ProcessingTaskTitle(BaseModel):
processing_status_union: ProcessingStatusUnionTitle | None = Field(
'COMPLETED', title='Processing Status Union Title', validate_default=True
)
processing_status: ProcessingStatusTitle | None = 'COMPLETED'
name: str | None = None
kind: Kind | None = None
class ProcessingTasksTitle(RootModel[list[ProcessingTaskTitle]]):
root: list[ProcessingTaskTitle] = Field(..., title='Processing Tasks Title')
class ExtendedProcessingTask(RootModel[ProcessingTasksTitle | NestedCommentTitle]):
root: ProcessingTasksTitle | NestedCommentTitle = Field(
..., title='Extended Processing Task Title'
)
class ExtendedProcessingTasksTitle(RootModel[list[ExtendedProcessingTask]]):
root: list[ExtendedProcessingTask] = Field(
..., title='Extended Processing Tasks Title'
)
class ProcessingStatusUnionTitle(
RootModel[ProcessingStatusDetail | ExtendedProcessingTask | ProcessingStatusTitle]
):
root: ProcessingStatusDetail | ExtendedProcessingTask | ProcessingStatusTitle = (
Field('COMPLETED', title='Processing Status Union Title', validate_default=True)
)
ProcessingTaskTitle.model_rebuild()