Skip to content

SkyTik/swagger-ui-python

Repository files navigation

tests Version

Documentation

swagger-ui-python

Seamless Swagger UI integration for Python web frameworks. A unified, framework-agnostic API for adding interactive OpenAPI documentation to your Python applications with automatic framework detection.

Note: This is a maintained fork of PWZER/swagger-ui-py.

Status: Production-ready, actively maintained Python: 3.9, 3.10, 3.11, 3.12 Swagger UI: v5.25.3 Swagger Editor: v4.14.6

Key Features

  • Framework Agnostic - Single API works across 9+ Python frameworks
  • Auto-Detection - Automatically detects your framework, zero configuration needed
  • Multiple Config Sources - YAML/JSON files, remote URLs, Python dicts, or strings
  • Swagger Editor - Optional inline spec editor for live documentation editing
  • Static Assets - Automatic CSS, JS, images, and icons serving
  • Customization - Custom CSS, Swagger UI parameters, OAuth2 configuration
  • Well-Tested - 50+ test cases across all supported frameworks

Supported Frameworks

Check supported frameworks:

python3 -c "from swagger_ui import supported_list; print(supported_list)"
# Output: ['flask', 'tornado', 'sanic', 'aiohttp', 'quart', 'starlette', 'falcon', 'bottle', 'chalice']

Quick Start

Installation

pip install swagger-ui-python

Basic Example (Flask)

from flask import Flask
from swagger_ui import api_doc

app = Flask(__name__)

# Auto-detects Flask and registers routes
api_doc(app, config_path='./openapi.yaml')

if __name__ == '__main__':
    app.run(debug=True)
    # Visit: http://localhost:5000/api/doc

Basic Example (Tornado)

import tornado.ioloop
from tornado.web import Application
from swagger_ui import api_doc

app = Application()

# Auto-detects Tornado and registers routes
api_doc(app, config_path='./openapi.yaml', url_prefix='/api/doc')

if __name__ == '__main__':
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
    # Visit: http://localhost:8888/api/doc

Configuration Options

1. Configuration Sources (in priority order)

Option A: YAML/JSON File

api_doc(app, config_path='./openapi.yaml')

Option B: Remote URL (requires CORS)

api_doc(app, config_url='https://petstore.swagger.io/v2/swagger.json')

Option C: Python Dict

config = {
    "openapi": "3.0.1",
    "info": {"title": "My API", "version": "1.0.0"},
    "paths": { ... }
}
api_doc(app, config=config)

Option D: JSON/YAML String

spec_string = '{"openapi":"3.0.1","info":{"title":"My API"},...}'
api_doc(app, config_spec=spec_string)

Option E: External Endpoint

api_doc(app, config_rel_url='/swagger.json')  # App provides endpoint

2. Common Parameters

api_doc(
    app,
    config_path='./openapi.yaml',      # Config source
    url_prefix='/api/doc',              # Internal route path (default: '/api/doc')
    base_url=None,                      # External URL for assets (defaults to url_prefix)
    title='API Documentation',          # HTML page title
    editor=False,                       # Enable spec editor
    custom_css='https://cdn.../style.css',  # Custom CSS
    host_inject=True,                   # Auto-inject request host
)

3. Reverse Proxy Support

When deploying behind a reverse proxy, you may need to separate internal route registration from external URL paths.

Common scenario: Reverse proxy routes /api/* to your backend service at root /

The Problem:

Without base_url, Swagger UI generates incorrect asset URLs:

api_doc(app, config_path='./openapi.yaml', url_prefix='/docs')
  • Backend registers routes at /docs
  • Browser requests /api/docs → proxy routes to backend /docs
  • But Swagger UI generates links like /docs/static/swagger-ui.css
  • Browser requests /docs/static/swagger-ui.css → 404 ✗ (missing /api prefix)

The Solution:

Use base_url to include the proxy path prefix in generated URLs:

api_doc(
    app,
    config_path='./openapi.yaml',
    url_prefix='/docs',        # Backend registers routes here
    base_url='/api/docs',      # Browser URLs include proxy prefix
)
  • Backend registers routes at /docs (unchanged)
  • Swagger UI generates links like /api/docs/static/swagger-ui.css
  • Browser requests /api/docs/static/swagger-ui.css → proxy routes to backend /docs/static/swagger-ui.css

Key distinction:

  • url_prefix - Where your app registers routes (backend/app-side)
  • base_url - Path prefix for URLs in HTML (browser/client-side, defaults to url_prefix)

4. Swagger UI Customization

parameters = {
    "deepLinking": "true",
    "displayRequestDuration": "true",
    "layout": "\"StandaloneLayout\"",
    "plugins": "[SwaggerUIBundle.plugins.DownloadUrl]",
}
api_doc(app, config_path='./openapi.yaml', parameters=parameters)

See Swagger UI Parameters for all options.

5. OAuth2 Configuration

oauth2_config = {
    "clientId": "\"your-client-id\"",
    "clientSecret": "\"your-secret\"",
    "realm": "\"your-realm\"",
    "appName": "\"your-app\"",
    "scopeSeparator": "\" \"",
    "scopes": "\"openid profile\"",
}
api_doc(app, config_path='./openapi.yaml', oauth2_config=oauth2_config)

See OAuth2 Configuration for details.

6. Legacy Framework-Specific APIs

Still supported for backward compatibility:

from swagger_ui import flask_api_doc, tornado_api_doc, sanic_api_doc

# Same as api_doc(app, ...) but explicit
flask_api_doc(app, config_path='./openapi.yaml')
tornado_api_doc(app, config_path='./openapi.yaml')
sanic_api_doc(app, config_path='./openapi.yaml')

Routes Created

The library automatically creates these routes (at url_prefix=/api/doc):

  • GET /api/doc - Interactive Swagger UI documentation
  • GET /api/doc/swagger.json - OpenAPI specification (JSON)
  • GET /api/doc/editor - Swagger Editor (if editor=True)
  • GET /api/doc/static/{path} - Static assets (CSS, JS, images)

Creating OpenAPI Specifications

For details on writing OpenAPI specifications:

Versions

  • Swagger UI: v5.25.3 (GitHub)
  • Swagger Editor: v4.14.6 (GitHub)

To update to newer versions:

tox -e update
# or
python tools/update.py --ui-version=v5.25.3 --editor-version=v4.14.6

Extending the Library

Adding Support for New Frameworks

To add support for a new framework:

  1. Create swagger_ui/handlers/{framework}.py following the handler interface
  2. Implement handler(doc) and match(doc) functions
  3. Add tests in test/{framework}_test.py
  4. Update README with framework name
  5. Auto-discovery will handle the rest

See Code Standards for detailed guidelines.

Custom Parameters & Configuration

Pass custom parameters and OAuth2 configuration through the api_doc() function for full control over Swagger UI behavior.

Documentation

Full documentation available in the ./docs directory:

Development

Setup

# Clone repository
git clone https://github.com/SkyTik/swagger-ui-python.git
cd swagger-ui-python

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
make pytest

# Format code
make format

# Build wheel
make whl

Testing

make pytest              # Run all tests
make format-check        # Check code style
make format              # Auto-format code

Building & Release

make whl                 # Build wheel
make upload              # Upload to PyPI

Troubleshooting

Framework not detected:

  • Ensure framework is installed
  • Try explicit app_type parameter: api_doc(app, app_type='flask', ...)

Config not loading:

  • Check file path exists and is readable
  • Validate YAML/JSON format using Swagger Editor
  • Check CORS headers if using remote URL

Routes not registered:

  • Ensure api_doc() called before app starts
  • Check url_prefix doesn't conflict with existing routes
  • Verify framework-specific setup (e.g., app.register_blueprint() for Flask)

For more help:

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure tests pass: make pytest
  5. Format code: make format
  6. Submit a pull request

See Code Standards for contribution guidelines.

License

Licensed under the Apache License 2.0. See LICENSE file for details.

Support

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 14