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