Metadata-Version: 2.4
Name: swagger-ui-python
Version: 1.0.0
Summary: Swagger UI for Python web framework, such as Tornado, Flask, Quart, Sanic and Falcon.
Author: SkyTik
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/SkyTik/swagger-ui-py
Project-URL: Repository, https://github.com/SkyTik/swagger-ui-py
Project-URL: Issues, https://github.com/SkyTik/swagger-ui-py/issues
Keywords: swagger,swagger-ui,openapi,api,documentation,flask,tornado,sanic,quart,falcon,aiohttp,starlette,bottle,chalice
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: jinja2>=2.0
Requires-Dist: packaging>=20.0
Requires-Dist: PyYaml>=5.0
Dynamic: license-file

[![tests](https://github.com/PWZER/swagger-ui-py/actions/workflows/lint-and-pytest.yml/badge.svg)](https://github.com/PWZER/swagger-ui-py/actions/workflows/lint-and-pytest.yml)
[![Version](https://badge.fury.io/gh/PWZER%2Fswagger-ui-py.svg)](https://github.com/PWZER/swagger-ui-py/tags)
[![PyPi Version](https://img.shields.io/pypi/v/swagger-ui-py.svg)](https://pypi.org/project/swagger-ui-py/)
[![PyPi Downloads](https://pepy.tech/badge/swagger-ui-py)](https://pepy.tech/project/swagger-ui-py)

[Project Page](https://pwzer.github.io/swagger-ui-py/) | [Documentation](./docs/)

# swagger-ui-py

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.

**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

- [Tornado](https://www.tornadoweb.org/en/stable/)
- [Flask](https://flask.palletsprojects.com/)
- [Sanic](https://sanicframework.org/en/)
- [AIOHTTP](https://docs.aiohttp.org/en/stable/)
- [Quart](https://pgjones.gitlab.io/quart/)
- [Starlette](https://www.starlette.io/)
- [Falcon](https://falcon.readthedocs.io/en/stable/)
- [Bottle](https://bottlepy.org/docs/dev/)
- [Chalice](https://aws.github.io/chalice/index.html)

Check supported frameworks:

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

## Quick Start

### Installation

```bash
pip install swagger-ui-py
```

### Basic Example (Flask)

```python
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)

```python
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**

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

**Option B: Remote URL** (requires CORS)

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

**Option C: Python Dict**

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

**Option D: JSON/YAML String**

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

**Option E: External Endpoint**

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

### 2. Common Parameters

```python
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 running behind a reverse proxy with a path prefix (e.g., ingress `/service/*` → backend), use `base_url` to set the external URL path for static assets:

```python
# Proxy routes /service/docs/* to backend /docs/*
api_doc(
    app,
    config_path='./openapi.yaml',
    url_prefix='/docs',              # Internal routes registered at /docs
    base_url='/service/docs',        # Assets linked as /service/docs/static/*
)
```

- `url_prefix` - Used for internal route registration (app-side)
- `base_url` - Used for asset URLs in HTML templates (browser-side, defaults to `url_prefix`)

### 4. Swagger UI Customization

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

See [Swagger UI Parameters](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/) for all options.

### 5. OAuth2 Configuration

```python
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](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/) for details.

### 6. Legacy Framework-Specific APIs

Still supported for backward compatibility:

```python
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:

- [OpenAPI 3.0 Guide](https://swagger.io/resources/open-api/)
- [OpenAPI 3.1 Spec](https://spec.openapis.org/oas/v3.1.0)
- [Swagger Editor](https://editor.swagger.io/) - Interactive spec editor

## Versions

- **Swagger UI:** v5.25.3 ([GitHub](https://github.com/swagger-api/swagger-ui))
- **Swagger Editor:** v4.14.6 ([GitHub](https://github.com/swagger-api/swagger-editor))

To update to newer versions:

```bash
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](./docs/system-architecture.md)
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](./docs/code-standards.md) 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:

- [Project Overview & PDR](./docs/project-overview-pdr.md) - Vision, goals, requirements
- [Codebase Summary](./docs/codebase-summary.md) - Module structure and responsibilities
- [Code Standards](./docs/code-standards.md) - Coding conventions and patterns
- [System Architecture](./docs/system-architecture.md) - Design patterns and data flow
- [Project Roadmap](./docs/project-roadmap.md) - Planned improvements and timeline

## Development

### Setup

```bash
# Clone repository
git clone https://github.com/PWZER/swagger-ui-py.git
cd swagger-ui-py

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

# Run tests
make pytest

# Format code
make format

# Build wheel
make whl
```

### Testing

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

### Building & Release

```bash
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](https://editor.swagger.io/)
- 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:
- Check [examples/](./examples/) directory for working samples
- Review [GitHub Issues](https://github.com/PWZER/swagger-ui-py/issues)
- Read framework-specific documentation

## 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](./docs/code-standards.md) for contribution guidelines.

## License

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

## Support

- **Issues:** [GitHub Issues](https://github.com/PWZER/swagger-ui-py/issues)
- **Project:** [PWZER/swagger-ui-py](https://github.com/PWZER/swagger-ui-py)
- **PyPI:** [swagger-ui-py](https://pypi.org/project/swagger-ui-py/)
