Generate from OpenAPI¶
The code generator can create pydantic models from OpenAPI schema definitions, particularly using the data from the schema field.
Example¶
api.yaml
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
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
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
description: "The URL describing the dataset's fields"
apiDocumentationUrl:
type: string
format: uri
description: A URL to the API console for each API
model.py
# generated by datamodel-codegen:
# filename: api.yaml
# timestamp: 2020-06-02T05:28:24+00:00
from __future__ import annotations
from typing import List, Optional
from pydantic import AnyUrl, BaseModel, Field
class Pet(BaseModel):
id: int
name: str
tag: Optional[str] = None
class Pets(BaseModel):
__root__: List[Pet]
class Error(BaseModel):
code: int
message: str
class Api(BaseModel):
apiKey: Optional[str] = Field(
None, description='To be used as a dataset parameter value'
)
apiVersionNumber: Optional[str] = Field(
None, description='To be used as a version parameter value'
)
apiUrl: Optional[AnyUrl] = Field(
None, description="The URL describing the dataset's fields"
)
apiDocumentationUrl: Optional[AnyUrl] = Field(
None, description='A URL to the API console for each API'
)
class Apis(BaseModel):
__root__: List[Api]
readOnly / writeOnly Properties¶
OpenAPI 3.x supports readOnly and writeOnly property annotations:
- readOnly: Property is only returned in responses (e.g.,
id,created_at) - writeOnly: Property is only sent in requests (e.g.,
password)
Option: --read-only-write-only-model-type¶
This option generates separate Request/Response models based on these annotations.
| Value | Description |
|---|---|
| (not set) | Default. No special handling (backward compatible) |
request-response |
Generate only Request/Response models (no base model) |
all |
Generate base model + Request + Response models |
Example Schema¶
openapi: "3.0.0"
info:
title: User API
version: "1.0"
paths: {}
components:
schemas:
User:
type: object
required:
- id
- name
properties:
id:
type: integer
readOnly: true # Server-generated, not in requests
name:
type: string
password:
type: string
writeOnly: true # Client-only, not in responses
created_at:
type: string
format: date-time
readOnly: true
Generated Output¶
$ datamodel-codegen --input user.yaml --input-file-type openapi \
--output-model-type pydantic_v2.BaseModel \
--read-only-write-only-model-type all
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
# Request model: excludes readOnly fields (id, created_at)
class UserRequest(BaseModel):
name: str
password: Optional[str] = None
# Response model: excludes writeOnly fields (password)
class UserResponse(BaseModel):
id: int
name: str
created_at: Optional[datetime] = None
# Base model: contains all fields
class User(BaseModel):
id: int
name: str
password: Optional[str] = None
created_at: Optional[datetime] = None
Usage Patterns¶
| Use Case | Recommended Option | Generated Models |
|---|---|---|
| API client validation | request-response |
UserRequest, UserResponse |
| Database ORM mapping | (not set) | User |
| Both client & ORM | all |
User, UserRequest, UserResponse |
Behavior with allOf Inheritance¶
When using allOf with $ref, fields from all referenced schemas are flattened into Request/Response models:
components:
schemas:
Timestamps:
type: object
properties:
created_at:
type: string
format: date-time
readOnly: true
User:
allOf:
- $ref: "#/components/schemas/Timestamps"
- type: object
properties:
name:
type: string
Generated UserRequest will exclude created_at (readOnly from Timestamps).
Collision Handling¶
If a schema named UserRequest or UserResponse already exists, the generated model will be named UserRequestModel or UserResponseModel to avoid conflicts.
Supported Output Formats¶
This option works with all output formats:
pydantic.BaseModel/pydantic_v2.BaseModeldataclasses.dataclasstyping.TypedDictmsgspec.Struct
Supported $ref Types¶
readOnly/writeOnly resolution works with local and file reference types:
| Reference Type | Example | Support |
|---|---|---|
| Local | #/components/schemas/User |
✅ |
| File | ./common.yaml#/User |
✅ |