tornado-swagger builds Swagger/OpenAPI documentation for Tornado applications from YAML blocks in request-handler docstrings. It can inject a Swagger UI endpoint into your route list and can also export the generated schema as a Python dictionary.
The default output is Swagger 2.0. Experimental OpenAPI 3 output is available with api_definition_version=API_OPENAPI_3 or api_definition_version=API_OPENAPI_3_1.
Links
Documentation: https://github.com/mrk-andreev/tornado-swagger/wiki
Source code: https://github.com/mrk-andreev/tornado-swagger
Issues: https://github.com/mrk-andreev/tornado-swagger/issues
Swagger 2.0 specification: https://swagger.io/specification/v2/
OpenAPI specification: https://swagger.io/specification/
Installation
pip install -U tornado-swagger
Requirements
Python 3.6 through 3.14
Tornado 5.0 or newer
PyYAML 5.4 or newer
Standards compatibility
tornado-swagger generates documents compatible with Swagger 2.0, OpenAPI 3.0.3, and OpenAPI 3.1.0. Compatibility tests validate generated documents against the corresponding standards. Valid operation, schema, parameter, response, request body, and security YAML blocks are passed through into the generated document for the selected standard.
Quick start
Add YAML documentation to Tornado handler method docstrings after a --- separator, then call setup_swagger before constructing the application.
import tornado.ioloop
import tornado.web
from tornado_swagger.setup import setup_swagger
class ExampleHandler(tornado.web.RequestHandler):
def get(self):
"""
---
tags:
- Example
summary: Get an example response
produces:
- application/json
responses:
200:
description: Successful response
"""
self.write({"ok": True})
routes = [
tornado.web.url(r"/api/example", ExampleHandler),
]
setup_swagger(
routes,
swagger_url="/api/doc",
api_base_url="/",
title="Example API",
api_version="1.0.0",
)
app = tornado.web.Application(routes)
app.listen(8080)
tornado.ioloop.IOLoop.current().start()
Open http://localhost:8080/api/doc to view Swagger UI. The generated schema is served at http://localhost:8080/api/doc/swagger.json.
Models and Parameters
Reusable definitions can be registered with decorators. For Swagger 2.0, refer to models with #/definitions/... and parameters with #/parameters/....
import tornado.web
from tornado_swagger.model import register_swagger_model
from tornado_swagger.parameter import register_swagger_parameter
class PostsDetailsHandler(tornado.web.RequestHandler):
def get(self, posts_id):
"""
---
tags:
- Posts
summary: Get posts details
description: posts full version
produces:
- application/json
parameters:
- $ref: '#/parameters/PostId'
responses:
200:
description: list of posts
schema:
$ref: '#/definitions/PostModel'
"""
@register_swagger_parameter
class PostId:
"""
---
name: posts_id
in: path
description: ID of post
required: true
type: string
"""
@register_swagger_model
class PostModel:
"""
---
type: object
description: Post model representation
properties:
id:
type: integer
format: int64
title:
type: string
text:
type: string
is_visible:
type: boolean
default: true
"""
OpenAPI 3
OpenAPI 3 support is available by passing API_OPENAPI_3 or API_OPENAPI_3_1 to setup_swagger or export_swagger. API_OPENAPI_3 emits OpenAPI 3.0.3, while API_OPENAPI_3_1 emits OpenAPI 3.1.0. OpenAPI 3 references use #/components/schemas/... and #/components/parameters/.... OpenAPI 3 security schemes can be passed with security_schemes.
from tornado_swagger.const import API_OPENAPI_3
from tornado_swagger.setup import setup_swagger
setup_swagger(
routes,
api_definition_version=API_OPENAPI_3,
)
JWT bearer authentication requires OpenAPI 3 because Swagger 2.0 does not support type: http security schemes.
from tornado_swagger.const import API_OPENAPI_3
from tornado_swagger.setup import setup_swagger
setup_swagger(
routes,
api_definition_version=API_OPENAPI_3,
security_schemes={
"BearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
},
},
security=[{"BearerAuth": []}],
)
Configuration
setup_swagger(routes, **kwargs) inserts Swagger UI and schema routes at the front of the supplied route list.
Supported options:
swagger_url: UI URL prefix. Defaults to /api/doc.
api_base_url: API base path in the generated schema. Defaults to /. Swagger 2 emits this as basePath; OpenAPI 3 emits it as servers[0].url.
strip_prefix: Optional route path prefix to remove from generated paths. Use this when Tornado routes include a deployment prefix that is already represented by api_base_url.
description: API description text.
api_version: API version string.
title: API title.
contact: Contact name included in the schema.
schemes: Swagger 2 scheme list, for example ["https"].
security_definitions: Swagger 2 security definitions to include in the schema. For backwards compatibility, OpenAPI 3 also accepts this option and emits it as components.securitySchemes.
security_schemes: OpenAPI 3 security schemes to include under components.securitySchemes.
security: Global security requirements.
display_models: Show or hide the Swagger UI models panel. Defaults to True.
api_definition_version: API_SWAGGER_2 by default, or API_OPENAPI_3 / API_OPENAPI_3_1.
allow_cors: Add CORS headers to Swagger UI and swagger.json responses (both the GET and preflight OPTIONS responses). Defaults to False.
cors_origin: Value for the Access-Control-Allow-Origin header when allow_cors is enabled. Defaults to "*". Set a specific origin (e.g. "https://example.com") to restrict cross-origin access; a Vary: Origin header is then added automatically.
swagger_ui_version: Swagger UI release loaded from cdnjs. Defaults to "4.13.2". When you change it, also pass the matching subresource integrity (SRI) hashes via the options below, otherwise the browser will block the assets.
swagger_ui_css_sri / swagger_ui_bundle_sri / swagger_ui_preset_sri: SRI hashes for swagger-ui.min.css, swagger-ui-bundle.min.js and swagger-ui-standalone-preset.min.js respectively. Defaults match swagger_ui_version’s default. Find the hashes for a given release on its cdnjs page. Pass empty strings to disable integrity checking.
To generate the schema without installing UI routes, use export_swagger:
from tornado_swagger.setup import export_swagger
schema = export_swagger(routes, title="Example API", api_version="1.0.0")
Examples
Runnable examples are available in the examples directory:
examples/simple_server.py: minimal Swagger UI setup.
examples/model_and_param_declaration.py: reusable Swagger 2 models and parameters.
examples/model_and_param_declaration_openapi3.py: OpenAPI 3 output.
examples/auth_server.py and examples/under_security/app.py: security-related examples.
examples/decorated_handlers.py: documented handlers with decorators.
examples/args_recognize.py: route argument name recognition.
Development
Install runtime and development dependencies, then run tests and linters with the Makefile targets:
pip install -r requirements-dev.txt make test make lint
Additional targets:
make format: run Ruff fixes and Black formatting.
make test-matrix: run the tox matrix.
make test-in-docker: run the Docker-based Python version matrix.
The tox matrix covers Tornado 5.0, 6.0, and 6.5.6 on older supported Python versions, and Tornado 6.5.6 on Python 3.11, 3.12, 3.13, and 3.14.
What’s new?
Version 1.7.0
Add strip_prefix option to setup_swagger and export_swagger so generated paths can remove a shared Tornado route prefix while api_base_url still emits Swagger 2 basePath or OpenAPI 3 servers[0].url (issue #72).
Version 1.6.0
Add OpenAPI 3.1 support and standards compatibility tests for Swagger 2.0, OpenAPI 3.0.3, and OpenAPI 3.1.0.
Add swagger_ui_version option to setup_swagger so the Swagger UI release loaded from cdnjs can be parametrized (defaults to 4.13.2).
Add swagger_ui_css_sri, swagger_ui_bundle_sri and swagger_ui_preset_sri options to supply matching subresource integrity hashes for a custom version (pass empty strings to disable integrity checking).
Fix allow_cors so CORS headers are also sent on the GET responses (previously only the preflight OPTIONS response carried them, so cross-origin spec fetches still failed in browsers).
Add cors_origin option to configure Access-Control-Allow-Origin instead of always using *.
Fix OpenAPI 3 server metadata generation and security scheme placement.
Add OpenAPI 3 JWT bearer authentication support.
Fix executable Swagger example endpoint and installation issue.
Add tox, Ruff linting, mypy checks, and broader test coverage.
Improve README and example documentation.
Version 1.5.0
Add allow_cors option (pull request #73). Thanks to @MarkParker5.
Version 1.4.5
Specify supported python versions: 3.7, 3.8, 3.9, 3.10, 3.11 and nightly
Remove flake8-eradicate, flake8-isort from dev deps
Create make test-in-docker for test application across python versions
Version 1.4.4
Fix path parsing with groups (skip + warning) (issue #58)
Version 1.4.3
Version 1.4.2
Update dev requirements (fix broken packages)
Update PyYAML from PyYAML==5.4 to PyYAML>=5.4 (issue #59)
Specify encoding in tornado_swagger/setup.py::open
Version 1.4.1
Fix pypi build (migrate README from md to rst)
Version 1.4.0
Add experimental openapi support (api_definition_version = API_OPENAPI_3; examples/model_and_param_declaration_openapi3.py)
Version 1.3.0
Add swagger parameter ref (@register_swagger_parameter). Thanks to @Weltraumpenner
Version 1.2.11
Fix link to spec swagger.json issue.
Version 1.2.10
Update PyYAML version to 5.4 (Fix for CVE-2020-14343)
Version 1.2.9
Fix handler args name parsing (examples/args_recognize.py). Thanks to @reubinoff
Version 1.2.8
Add security to setup. Thanks to @daominwang
Add black code formatter
Update swagger-ui library to 3.37.2
Add integrity attribute to script / link tags
Remove Python 3.5 support
Version 1.2.7
Add display_models param to setup (defaultModelsExpandDepth). Thanks to @Sloknatos
Fix swagger-ui bundle CVE-2019-17495
Specify supported python versions: 3.5, 3.6, 3.7, 3.8, nightly
Version 1.2.6
Fix issue with StaticFileHandler (https://github.com/mrk-andreev/tornado-swagger/pull/28)
Version 1.2.5
Update dependencies
PyYAML==5.3.1 fix vulnerabilities
pytest==6.0.1, pytest-flake8==1.0.6 fix test crash
Version 1.2.4
Fix “index out of range issue for StaticFileHandler” (https://github.com/mrk-andreev/tornado-swagger/issues/23)
Version 1.2.3
Fix \t bug in Windows (https://github.com/mrk-andreev/tornado-swagger/issues/21)
Version 1.2.1
Support wrapped methods
Remove jinja2 from deps
Version 1.2.0
Replace local js/css to cdn
Remove static files serving
Version 1.1.0
Swagger model definition
Parameters filling in route path
Schema definition
export_swagger(routes) as public function
Update frontend
Version 1.0.0
First version released
License
Release files for tornado-swagger 1.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tornado_swagger-1.7.0.tar.gz | 23.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tornado_swagger-1.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.2 kB
Release files / tornado_swagger-1.7.0.tar.gz
| Download URL | tornado_swagger-1.7.0.tar.gz |
|---|---|
| Size | 23.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
afe93600c2dac4f699ac1edd00f374a03ac5cff8ba8ebf522598d8aa58eac6f0
|
|
BLAKE2b-256 checksum How to use checksums |
0f9f4151a147c44c5433d08725a014b89c7767c228999a7ce1465d01278759e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.
Transparency logRelease files / tornado_swagger-1.7.0-py3-none-any.whl
| Download URL | tornado_swagger-1.7.0-py3-none-any.whl |
|---|---|
| Size | 15.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
170c26811c7cb473a76197bb643ba409f5f0b8593ce27e5a212fd139be2fcbad
|
|
BLAKE2b-256 checksum How to use checksums |
2e0954d45ff11ea51c432a8026d111d168b093042fde9d929a5900a61b03ce19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.
Transparency log