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.
- 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
- PyPI: https://pypi.org/project/tornado-swagger/
- Swagger 2.0 specification: https://swagger.io/specification/v2/
- OpenAPI specification: https://swagger.io/specification/
pip install -U tornado-swagger
- Python 3.6 through 3.14
- Tornado 5.0 or newer
- PyYAML 5.4 or newer
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.
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.
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 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": []}],
)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 asbasePath; OpenAPI 3 emits it asservers[0].url.strip_prefix: Optional route path prefix to remove from generatedpaths. Use this when Tornado routes include a deployment prefix that is already represented byapi_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 ascomponents.securitySchemes.security_schemes: OpenAPI 3 security schemes to include undercomponents.securitySchemes.security: Global security requirements.display_models: Show or hide the Swagger UI models panel. Defaults toTrue.api_definition_version:API_SWAGGER_2by default, orAPI_OPENAPI_3/API_OPENAPI_3_1.allow_cors: Add CORS headers to Swagger UI andswagger.jsonresponses (both theGETand preflightOPTIONSresponses). Defaults toFalse.cors_origin: Value for theAccess-Control-Allow-Originheader whenallow_corsis enabled. Defaults to"*". Set a specific origin (e.g."https://example.com") to restrict cross-origin access; aVary: Originheader 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 forswagger-ui.min.css,swagger-ui-bundle.min.jsandswagger-ui-standalone-preset.min.jsrespectively. Defaults matchswagger_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")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.pyandexamples/under_security/app.py: security-related examples.examples/decorated_handlers.py: documented handlers with decorators.examples/args_recognize.py: route argument name recognition.
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.
- Add
strip_prefixoption tosetup_swaggerandexport_swaggerso generatedpathscan remove a shared Tornado route prefix whileapi_base_urlstill emits Swagger 2basePathor OpenAPI 3servers[0].url(issue #72).
- 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_versionoption tosetup_swaggerso the Swagger UI release loaded from cdnjs can be parametrized (defaults to4.13.2). - Add
swagger_ui_css_sri,swagger_ui_bundle_sriandswagger_ui_preset_srioptions to supply matching subresource integrity hashes for a custom version (pass empty strings to disable integrity checking). - Fix
allow_corsso CORS headers are also sent on theGETresponses (previously only the preflightOPTIONSresponse carried them, so cross-origin spec fetches still failed in browsers). - Add
cors_originoption to configureAccess-Control-Allow-Origininstead 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.
- Add
allow_corsoption (pull request #73). Thanks to @MarkParker5.
- Specify supported python versions: 3.7, 3.8, 3.9, 3.10, 3.11 and nightly
- Remove
flake8-eradicate,flake8-isortfrom dev deps - Create
make test-in-dockerfor test application across python versions
- Fix path parsing with groups (skip + warning) (issue #58)
- Update dev requirements (fix broken packages)
- Update PyYAML from
PyYAML==5.4toPyYAML>=5.4(issue #59) - Specify encoding in
tornado_swagger/setup.py::open
- Fix pypi build (migrate README from md to rst)
- Add experimental openapi support (api_definition_version = API_OPENAPI_3; examples/model_and_param_declaration_openapi3.py)
- Add swagger parameter ref (@register_swagger_parameter). Thanks to @Weltraumpenner
- Fix link to spec swagger.json issue.
- Update PyYAML version to 5.4 (Fix for CVE-2020-14343)
- Fix handler args name parsing (
examples/args_recognize.py). Thanks to @reubinoff
- Add
securityto 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
- 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
- Fix issue with
StaticFileHandler(#28)
- Update dependencies
PyYAML==5.3.1fix vulnerabilitiespytest==6.0.1,pytest-flake8==1.0.6fix test crash
- Fix “index out of range issue for StaticFileHandler” (#23)
- Fix
\tbug in Windows (#21)
- Support wrapped methods
- Remove jinja2 from deps
- Replace local js/css to cdn
- Remove static files serving
- Swagger model definition
- Parameters filling in route path
- Schema definition
export_swagger(routes)as public function- Update frontend
- First version released