Files
2026-06-02 16:26:10 +08:00

99 lines
3.1 KiB
Python

import os
import typing
import tornado
import tornado.web
from tornado_swagger._builders import generate_doc_from_endpoints
from tornado_swagger._handlers import TornadoBaseHandler
from tornado_swagger.const import API_SWAGGER_2
from tornado_swagger.setup import STATIC_PATH
from paste.web.application import ApplicationSwagger
class SwaggerUiHandler(TornadoBaseHandler):
"""
自定义 Ui,支持从应用程序读取文档页面。
主要是为了允许不同的应用具有不同的接口描述页面。
"""
def get(self):
if hasattr(self.application, 'swagger_home_template'):
self.write(self.application.swagger_home_template)
else:
self.write(
f'类型错误,无法从应用程序读取 swagger_home_template 属性,'
f'请使用 ApplicationSwagger 以支持 Swagger。'
)
class SwaggerSpecHandler(TornadoBaseHandler):
"""
自定义 Spec,支持从应用程序读取 Schema。
主要是为了允许不同的应用具有不同的接口描述页面。
"""
def get(self):
if hasattr(self.application, 'swagger_schema'):
self.write(self.application.swagger_schema)
else:
self.write(
f'类型错误,无法从应用程序读取 swagger_schema 属性,'
f'请使用 ApplicationSwagger 以支持 Swagger。'
)
def setup_swagger(
app: ApplicationSwagger,
routes: typing.List[tornado.web.URLSpec],
*,
swagger_url: str = "/api/doc",
api_base_url: str = "/",
description: str = "Swagger API definition",
api_version: str = "1.0.0",
title: str = "Swagger API",
contact: str = "",
schemes: list = None,
security_definitions: dict = None,
security: list = None,
display_models: bool = True,
api_definition_version: str = API_SWAGGER_2
):
"""
注入 Swagger ui 到应用程序路由。
"""
swagger_schema = generate_doc_from_endpoints(
routes,
api_base_url=api_base_url,
description=description,
api_version=api_version,
title=title,
contact=contact,
schemes=schemes,
security_definitions=security_definitions,
security=security,
api_definition_version=api_definition_version,
)
_swagger_ui_url = f"/{swagger_url}" if not swagger_url.startswith("/") else swagger_url
_base_swagger_ui_url = _swagger_ui_url.rstrip("/")
_swagger_spec_url = f"{_swagger_ui_url}/swagger.json"
routes[:0] = [
tornado.web.url(_swagger_ui_url, SwaggerUiHandler),
tornado.web.url(f"{_base_swagger_ui_url}/", SwaggerUiHandler),
tornado.web.url(_swagger_spec_url, SwaggerSpecHandler),
]
app.swagger_schema = swagger_schema
with open(os.path.join(STATIC_PATH, "ui.html"), "r", encoding="utf-8") as f:
app.swagger_home_template = (
f.read().replace(
"{{ SWAGGER_URL }}", _swagger_spec_url
).replace(
"{{ DISPLAY_MODELS }}", str(-1 if not display_models else 1)
)
)