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 pyyamland 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
- Start the application in a headless mode (e.g., using
uvicorn --port 0). - Request
/openapi.jsonand save it to the repository (or an artifact store). - Run
swagger-cli validate openapi.jsonto catch schema errors early. - Optionally, generate client SDKs with
openapi-generator-cliand 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
Leave a Reply