📘 Generate from OpenAPI¶
Generate Pydantic models from OpenAPI 3 schema definitions.
🚀 Quick Start¶
📝 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
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
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"
/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"
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
✨ Generated model.py:
# generated by datamodel-codegen:
# filename: api.yaml
from __future__ import annotations
from pydantic import BaseModel, RootModel
class Pet(BaseModel):
id: int
name: str
tag: str | None = None
class Pets(RootModel[list[Pet]]):
root: list[Pet]
class Error(BaseModel):
code: int
message: str
📖 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 |
✅ Supported |
| File | ./common.yaml#/User |
✅ Supported |
📖 See Also¶
- 🖥️ CLI Reference: OpenAPI-only Options - All OpenAPI-specific CLI options
- ⚙️ CLI Reference: Base Options - Input/output configuration options