Python Openapi Auto Documentation Guide

Written by

in

Generating up‑to‑date API documentation can feel like a never‑ending chore, especially when your Python services evolve quickly. Fortunately, the OpenAPI specification (formerly Swagger) and modern Python frameworks make it possible to automate the entire documentation pipeline with just a few lines of code. In this guide we’ll walk through everything you need to know to set up **Python OpenAPI auto documentation**, from choosing the right library to customizing the UI and deploying the spec for public consumption.

Why Choose OpenAPI for Python Projects?

OpenAPI is the industry‑standard format for describing RESTful APIs. It offers several tangible benefits for Python developers:

  • Language‑agnostic contracts: Clients in any language can generate SDKs directly from the spec.
  • Interactive documentation: Tools like Swagger UI and Redoc turn a JSON/YAML file into a live, testable API explorer.
  • Automation: When your code changes, the spec can be regenerated automatically, eliminating stale docs.
  • Validation & testing: Request/response schemas can be validated at runtime, catching errors early.

Popular Python Frameworks with Built‑in OpenAPI Support

Not all Python web frameworks handle OpenAPI equally. Below are the three most common choices for auto‑generated documentation.

FastAPI

FastAPI was built around OpenAPI from day one. Every endpoint automatically contributes to an OpenAPI schema, which is served at /openapi.json. Swagger UI and Redoc are available at /docs and /redoc respectively, without extra configuration.

Flask + Flask‑RESTX

Flask itself is minimal, but the flask-restx extension adds declarative route definitions and an api object that can generate a spec. The UI is served at /swagger/ by default.

Django REST framework (DRF) + drf‑spectacular

DRF focuses on serializers and viewsets. The drf-spectacular package introspects those components to produce a clean OpenAPI 3.0 document, which can be rendered with Swagger UI or Redoc.

Step‑by‑Step: Auto‑Documenting a FastAPI Service

FastAPI provides the smoothest experience, so we’ll use it as our primary example. Follow these steps to get a fully functional, auto‑generated OpenAPI doc.

1. Install FastAPI and an ASGI server

pip install fastapi uvicorn

2. Create a simple API

from fastapi import FastAPI, Path
from pydantic import BaseModel

app = FastAPI(title="Book Store API", version="1.0.0")

class Book(BaseModel):
    id: int
    title: str
    author: str
    price: float

# In‑memory store for demonstration
books = {
    1: Book(id=1, title="1984", author="George Orwell", price=9.99),
    2: Book(id=2, title="Brave New World", author="Aldous Huxley", price=12.50),
}

@app.get("/books", response_model=list[Book])
def list_books():
    """Return a list of all books."""
    return list(books.values())

@app.get("/books/{book_id}", response_model=Book)
def get_book(book_id: int = Path(..., gt=0)):
    """Retrieve a single book by its ID."""
    return books[book_id]

@app.post("/books", response_model=Book, status_code=201)
def create_book(book: Book):
    """Add a new book to the store."""
    books[book.id] = book
    return book

3. Run the server

uvicorn main:app --reload

Once the server is up, visit http://127.0.0.1:8000/docs for Swagger UI or http://127.0.0.1:8000/redoc for Redoc. Both pages are generated from the OpenAPI spec automatically.

4. Customizing the OpenAPI Metadata

You can enrich the spec with additional information such as contact details, license, or external documentation.

app = FastAPI(
    title="Book Store API",
    version="1.0.0",
    description="A tiny example API to demonstrate FastAPI's auto‑generated OpenAPI docs.",
    terms_of_service="https://example.com/terms/",
    contact={
        "name": "API Support",
        "url": "https://example.com/support",
        "email": "support@example.com",
    },
    license_info={"name": "MIT", "url": "https://opensource.org/licenses/MIT"},
)

5. Adding Tags and Summaries

Tags group endpoints in the UI, while summary and description provide concise documentation.

@app.get("/books", response_model=list[Book], tags=["Books"], summary="List all books")
def list_books():
    ...

Generating a Stand‑Alone OpenAPI File

Sometimes you need the raw openapi.json or openapi.yaml for CI pipelines, SDK generation, or third‑party portals.

  • JSON: curl http://127.0.0.1:8000/openapi.json -o openapi.json
  • YAML: Use a conversion tool like pip install pyyaml and run a small script to dump the JSON as YAML.

Auto‑Documentation with Flask‑RESTX

If you’re already on Flask, flask-restx adds OpenAPI support with minimal boilerplate.

Installation

pip install flask-restx

Basic Example

from flask import Flask
from flask_restx import Api, Resource, fields

app = Flask(__name__)
api = Api(app,
          version="1.0",
          title="Todo API",
          description="A simple Todo API with auto‑generated docs")

todo = api.model('Todo', {
    'id': fields.Integer(readOnly=True, description='The unique identifier'),
    'task': fields.String(required=True, description='Task description')
})

TODOS = []

@api.route('/todos')
class TodoList(Resource):
    @api.marshal_list_with(todo)
    def get(self):
        """List all todos"""
        return TODOS

    @api.expect(todo)
    @api.marshal_with(todo, code=201)
    def post(self):
        """Create a new todo"""
        new = api.payload
        new['id'] = len(TODOS) + 1
        TODOS.append(new)
        return new, 201

if __name__ == '__main__':
    app.run(debug=True)

Navigate to http://localhost:5000/ and you’ll see Swagger UI rendered automatically.

Integrating OpenAPI Generation into CI/CD

Automation doesn’t stop at runtime. By adding a step to your CI pipeline you can ensure the spec is always in sync with the codebase.

Typical Workflow

  1. Start the application in a headless mode (e.g., using uvicorn --port 0).
  2. Request /openapi.json and save it to the repository (or an artifact store).
  3. Run swagger-cli validate openapi.json to catch schema errors early.
  4. Optionally, generate client SDKs with openapi-generator-cli and publish them.

Sample GitHub Actions Step

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - name: Install dependencies
        run: pip install fastapi uvicorn
      - name: Start API in background
        run: |
          uvicorn main:app --port 8000 &
          echo $! > uvicorn.pid
          sleep 5
      - name: Download OpenAPI spec
        run: |
          curl http://localhost:8000/openapi.json -o openapi.json
      - name: Validate spec
        run: npx @apidevtools/swagger-cli validate openapi.json

Customizing the Documentation UI

Both Swagger UI and Redoc are highly configurable through query parameters or a custom HTML template.

Swagger UI Options

  • url – point to a remote spec file.
  • docExpansion – control how sections are collapsed (e.g., none, list, full).
  • defaultModelsExpandDepth – set the depth of model expansion.

Example: http://localhost:8000/docs?url=/openapi.json&docExpansion=none

Redoc Custom Theme

Redoc allows a JSON theme object for branding.

app = FastAPI(
    redoc_url="/redoc",
    redoc_opts={"theme": {"colors": {"primary": {"main": "#4caf50"}}}}
)

Best Practices for Maintaining Clean OpenAPI Specs

  • Version your

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *