Skip to content

fastapi-code-generator

fastapi-code-generator creates a FastAPI application from an OpenAPI document.

This site is the source of truth for the project documentation. The repository README.md stays intentionally shorter and links back here for the complete walkthrough.

What it does

  • Generate a FastAPI app skeleton directly from an OpenAPI schema
  • Reuse datamodel-code-generator model generation for Pydantic and related output types
  • Support default single-file output and modular router-based output for larger applications
  • Allow custom Jinja templates and custom visitors for project-specific generation

Installation

uv tool install fastapi-code-generator
pip install fastapi-code-generator

Quick Start

Generate an application from an OpenAPI document:

fastapi-codegen --input api.yaml --output app

Use Pydantic v2 models for new projects:

fastapi-codegen --input api.yaml --output app --output-model-type pydantic_v2.BaseModel

For the full option matrix and tested examples, see the CLI reference.

CLI Help Snapshot

This block is generated from the current fastapi-codegen --help output so the overview page and the README stay aligned.

Usage: fastapi-codegen [OPTIONS]

Options:
  -e, --encoding TEXT             [default: utf-8]
  -i, --input TEXT                [required]
  -o, --output PATH               [required]
  -m, --model-file TEXT
  -t, --template-dir PATH
  --model-template-dir PATH
  --enum-field-as-literal [all|one]
  -r, --generate-routers
  --specify-tags TEXT
  -c, --custom-visitor PATH
  --disable-timestamp
  -d, --output-model-type [pydantic.BaseModel|pydantic_v2.BaseModel|dataclasses.dataclass|typing.TypedDict|msgspec.Struct]
                                  [default: pydantic.BaseModel]
  -p, --python-version [3.9|3.10|3.11|3.12|3.13|3.14]
                                  [default: 3.10]
  -V, --version
  --install-completion            Install completion for the current shell.
  --show-completion               Show completion for the current shell, to
                                  copy it or customize the installation.
  --help                          Show this message and exit.

End-to-End Example

Input schema

api.yaml
openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      responses:
        "200":
          description: A paged array of pets
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
    post:
      summary: Create a pet
      operationId: createPets
      responses:
        "201":
          description: Null response
  /pets/{petId}:
    get:
      summary: Info for a specific pet
      operationId: showPetById
      parameters:
        - name: petId
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
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"

Generate the app

fastapi-codegen --input api.yaml --output app

Generated app/main.py

# generated by fastapi-codegen:
#   filename:  api.yaml

from __future__ import annotations

from fastapi import FastAPI, Query

from .models import Pets

app = FastAPI(version="1.0.0", title="Swagger Petstore")


@app.get("/pets", response_model=Pets)
def list_pets() -> Pets:
    """
    List all pets
    """
    pass


@app.post("/pets", response_model=None)
def create_pets() -> None:
    """
    Create a pet
    """
    pass


@app.get("/pets/{pet_id}", response_model=Pets)
def show_pet_by_id(pet_id: str = Query(..., alias="petId")) -> Pets:
    """
    Info for a specific pet
    """
    pass

Generated app/models.py

# generated by datamodel-codegen:
#   filename:  api.yaml

from typing import List, Optional

from pydantic import BaseModel


class Pet(BaseModel):
    id: int
    name: str
    tag: Optional[str] = None


class Pets(BaseModel):
    __root__: List[Pet]

Custom Templates

Pass a template directory with --template-dir to render custom *.py files alongside the built-in templates:

fastapi-codegen --input api.yaml --output app --template-dir some_jinja_templates

Template files are discovered under the provided directory. A file such as some_jinja_templates/list_pets.py is rendered into app/list_pets.py.

Useful template variables:

Variable Meaning
imports Imports collected for the generated application
info Parsed info object from the OpenAPI document
operations All parsed operations available to the template
routers Router module names generated from tags when --generate-routers is enabled
tags Original OpenAPI tags used to build router output

Example main.jinja2:

from __future__ import annotations

from fastapi import FastAPI

{{imports}}

app = FastAPI(
    {% if info %}
    {% for key, value in info.items() %}
    {{ key }}="{{ value }}",
    {% endfor %}
    {% endif %}
)

{% for operation in operations %}
@app.{{operation.type}}("{{operation.snake_case_path}}", response_model={{operation.response}})
def {{operation.function_name}}({{operation.snake_case_arguments}}) -> {{operation.response}}:
    {%- if operation.summary %}
    """
    {{ operation.summary }}
    """
    {%- endif %}
    pass
{% endfor %}

Custom Visitors

Custom visitors can add project-specific variables before template rendering. Point --custom-visitor at one or more Python files:

fastapi-codegen --input api.yaml --output app --template-dir template --custom-visitor visitor.py

Example visitor:

from pathlib import Path

from fastapi_code_generator.parser import OpenAPIParser
from fastapi_code_generator.visitor import Visitor


def custom_visitor(parser: OpenAPIParser, model_path: Path) -> dict[str, object]:
    return {"custom_header": "Generated for my project"}


visit: Visitor = custom_visitor

Example template usage:

{{ custom_header }}
from __future__ import annotations

Modular Router Generation

Use --generate-routers with the built-in modular_template to generate one router module per tag:

fastapi-codegen --input swagger.yaml --output app --template-dir modular_template --generate-routers

Regenerate only selected routers:

fastapi-codegen --input swagger.yaml --output app --template-dir modular_template --generate-routers --specify-tags "Wild Boars, Fat Cats"

Typical output structure:

app/
├── main.py
├── models.py
├── dependencies.py
└── routers/
    ├── fat_cats.py
    ├── slim_dogs.py
    └── wild_boars.py

FastAPI's Bigger Applications guide is a good companion for organizing the generated routers.

Next Steps