From 1ee7b6d1c38e9eb80467cd57d9f9b1421415cde3 Mon Sep 17 00:00:00 2001 From: Noa Aviel Dove Date: Tue, 19 Nov 2024 18:59:22 -0800 Subject: [PATCH] Extract inline JS in Swagger UI to initializer script --- src/azul/chalice.py | 16 ++-- swagger/index.html | 19 +++++ swagger/index.html.template.mustache | 74 ------------------- swagger/swagger-initializer.js | 20 +++++ .../swagger-initializer.js.template.mustache | 43 +++++++++++ 5 files changed, 90 insertions(+), 82 deletions(-) create mode 100644 swagger/index.html delete mode 100644 swagger/index.html.template.mustache create mode 100644 swagger/swagger-initializer.js create mode 100644 swagger/swagger-initializer.js.template.mustache diff --git a/src/azul/chalice.py b/src/azul/chalice.py index 0e91e3975..98717713c 100644 --- a/src/azul/chalice.py +++ b/src/azul/chalice.py @@ -531,12 +531,11 @@ def swagger_redirect(self) -> Response: body='', headers={'Location': str(self.self_url.set(path='static/index.html'))}) - def swagger_ui(self) -> Response: - swagger_ui_template = self.load_static_resource('swagger', 'index.html.template.mustache') + def _expand_swagger_template(self, template: str) -> str: base_url = self.base_url redirect_url = furl(base_url).add(path='oauth2_redirect') deployment_url = furl(base_url).add(path='openapi') - swagger_ui_html = chevron.render(swagger_ui_template, { + return chevron.render(template, { 'DEPLOYMENT_PATH': json.dumps(str(deployment_url.path)), 'OAUTH2_CLIENT_ID': json.dumps(config.google_oauth2_client_id), 'OAUTH2_REDIRECT_URL': json.dumps(str(redirect_url)), @@ -545,19 +544,20 @@ def swagger_ui(self) -> Response: for path, method in self.non_interactive_routes ]) }) - return Response(status_code=200, - headers={'Content-Type': 'text/html'}, - body=swagger_ui_html) def swagger_resource(self, file) -> Response: if os.sep in file: raise BadRequestError(file) else: + templated_file = 'swagger-initializer.js' + stored_file = file + '.template.mustache' if file == templated_file else file try: - body = self.load_static_resource('swagger', file) + body = self.load_static_resource('swagger', stored_file) except FileNotFoundError: raise NotFoundError(file) else: + if file == templated_file: + body = self._expand_swagger_template(body) path = pathlib.Path(file) content_type = mimetypes.types_map[path.suffix] return Response(status_code=200, @@ -713,7 +713,7 @@ def swagger_redirect(): } ) def swagger_ui(): - return self.swagger_ui() + return self.swagger_resource('index.html') @self.route( '/openapi', diff --git a/swagger/index.html b/swagger/index.html new file mode 100644 index 000000000..84ae62d3d --- /dev/null +++ b/swagger/index.html @@ -0,0 +1,19 @@ + + + + + + Swagger UI + + + + + + + +
+ + + + + diff --git a/swagger/index.html.template.mustache b/swagger/index.html.template.mustache deleted file mode 100644 index 6928db38d..000000000 --- a/swagger/index.html.template.mustache +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - Swagger UI - - - - - -
- - - - - \ No newline at end of file diff --git a/swagger/swagger-initializer.js b/swagger/swagger-initializer.js new file mode 100644 index 000000000..8ea0ea3af --- /dev/null +++ b/swagger/swagger-initializer.js @@ -0,0 +1,20 @@ +window.onload = function() { + // + + // the following lines will be replaced by docker/configurator, when it runs in a docker-container + window.ui = SwaggerUIBundle({ + url: "https://petstore.swagger.io/v2/swagger.json", + dom_id: '#swagger-ui', + deepLinking: true, + presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIStandalonePreset + ], + plugins: [ + SwaggerUIBundle.plugins.DownloadUrl + ], + layout: "StandaloneLayout" + }); + + // +}; diff --git a/swagger/swagger-initializer.js.template.mustache b/swagger/swagger-initializer.js.template.mustache new file mode 100644 index 000000000..f7467aa1d --- /dev/null +++ b/swagger/swagger-initializer.js.template.mustache @@ -0,0 +1,43 @@ +window.onload = function() { + // + + // Adapted from https://github.com/swagger-api/swagger-ui/issues/3725#issuecomment-334899276 + const DisableTryItOutPlugin = function() { + return { + statePlugins: { + spec: { + wrapSelectors: { + allowTryItOutFor: (oriSelector, system) => (state, ...args) => { + return oriSelector(state, ...args) && ({{{NON_INTERACTIVE_METHODS}}}.indexOf(args.join('/')) == -1); + } + } + } + } + } + } + + window.ui = SwaggerUIBundle({ + url: {{{DEPLOYMENT_PATH}}}, + dom_id: '#swagger-ui', + deepLinking: true, + presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIStandalonePreset + ], + plugins: [ + SwaggerUIBundle.plugins.DownloadUrl, + DisableTryItOutPlugin + ], + oauth2RedirectUrl: {{{OAUTH2_REDIRECT_URL}}}, + layout: "StandaloneLayout" + }); + + const client_id = {{{OAUTH2_CLIENT_ID}}}; + if (client_id !== null) { + window.ui.initOAuth({ + clientId: client_id + }) + } + + // +};