From 5a66600f9a369fef558ae9ec6471e7b093567d35 Mon Sep 17 00:00:00 2001 From: Eugene Toder Date: Wed, 12 Jun 2024 22:32:20 -0400 Subject: [PATCH] Fix passing redoc UI parameters Currently passing redoc UI parameters has the following issues: * It puts json-ed values of parameters in single quotes, which breaks if the value itself contains single quotes. * If the value is falsy, only the name of the parameter is used. This syntax is *not* treated as falsy by redoc. The latter causes the download button to be always hidden, because the default parameters have "hide-download-button": False. There is no way to un-hide it with the current code. Change this to use the javascript API to pass UI parameters[1], which is much simpler and more robust. Also, stop using the "next" version of redoc, as suggested here[2]. This was an old release candidate for version 2. Use the officially released version 2. [1] https://redocly.com/docs/redoc/deployment/html/#the-redoc-object [2] https://github.com/tiangolo/fastapi/pull/9700 --- src/openapipages/redoc.py | 24 +++++++++++------------- tests/test_redoc.py | 3 ++- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/openapipages/redoc.py b/src/openapipages/redoc.py index a005423..81c5c63 100644 --- a/src/openapipages/redoc.py +++ b/src/openapipages/redoc.py @@ -19,7 +19,7 @@ "theme": { "typography": {"code": {"wrap": True}}, }, - "hide-download-button": False, + "hideDownloadButton": False, } @@ -35,7 +35,7 @@ class ReDoc(Base): It is normally set to a CDN URL. """ ), - ] = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js" + ] = "https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js" with_google_fonts: Annotated[ bool, Doc( @@ -64,15 +64,6 @@ def render(self) -> str: current_redoc_ui_parameters = default_parameters.copy() current_redoc_ui_parameters.update(self.ui_parameters or {}) - def add_redoc_ui_parameters() -> str: - _props = "" - for key, value in current_redoc_ui_parameters.items(): - if value: - _props += f"{key}='{json.dumps(value)}' " - else: - _props += f"{key} " - return _props - html_template = self.get_html_template() return html_template.format( title=self.title, @@ -82,7 +73,7 @@ def add_redoc_ui_parameters() -> str: head_js_str=self.get_head_js_str(), tail_js_str=self.get_tail_js_str(), google_fonts_str=google_fonts_str, - redoc_ui_parameters=add_redoc_ui_parameters(), + redoc_ui_parameters=json.dumps(current_redoc_ui_parameters, indent=2), ) def get_html_template(self) -> str: @@ -109,8 +100,15 @@ def get_html_template(self) -> str: - +
{tail_js_str} + """ diff --git a/tests/test_redoc.py b/tests/test_redoc.py index ad5696c..ae2d79a 100644 --- a/tests/test_redoc.py +++ b/tests/test_redoc.py @@ -10,7 +10,8 @@ def test_redoc_plain() -> None: response = client.get("/redoc-plain") assert response.status_code == 200, response.text assert response.headers["content-type"] == "text/html; charset=utf-8" - assert "redoc@next" in response.text + assert "redoc@2" in response.text + assert '"hideDownloadButton": false' in response.text def test_redoc_custom() -> None: