From bbebd8dd6b195ba9208cea7bd79e8c0f62405d7e Mon Sep 17 00:00:00 2001 From: benefactarch Date: Wed, 18 Oct 2023 10:59:51 -0400 Subject: [PATCH 1/8] Add support for custom Swagger UI files URL sources --- blacksheep/server/openapi/ui.py | 55 ++++++++++++++++++++++++--- blacksheep/server/res/redoc-ui.html | 4 +- blacksheep/server/res/swagger-ui.html | 38 +++++++++--------- 3 files changed, 70 insertions(+), 27 deletions(-) diff --git a/blacksheep/server/openapi/ui.py b/blacksheep/server/openapi/ui.py index c713694c..97680c2c 100644 --- a/blacksheep/server/openapi/ui.py +++ b/blacksheep/server/openapi/ui.py @@ -1,12 +1,31 @@ from abc import ABC, abstractmethod from dataclasses import dataclass -from typing import Callable +from typing import Callable, Optional from blacksheep.messages import Request, Response from blacksheep.server.files.static import get_response_for_static_content from blacksheep.server.resources import get_resource_file_content from blacksheep.utils.time import utcnow +SWAGGER_UI_CDN = ( + "https://cdn.jsdelivr.net/npm/swagger-ui-dist@3.30.0/swagger-ui-bundle.js" +) +SWAGGER_UI_CSS = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@3.30.0/swagger-ui.css" +SWAGGER_UI_FONT = None + +REDOC_UI_CDN = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js" +REDOC_UI_CSS = None +REDOC_UI_FONT = ( + "https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" +) + + +@dataclass +class CdnOptions: + js_cdn_url: str + css_cdn_url: Optional[str] = None + fontset_cdn_url: Optional[str] = None + @dataclass class UIOptions: @@ -15,9 +34,19 @@ class UIOptions: class UIProvider(ABC): - def __init__(self, ui_path: str) -> None: + cdn: CdnOptions + ui_path: str + + _default_cdn: CdnOptions + + def __init__( + self, + ui_path: str, + cdn: Optional[CdnOptions] = None, + ) -> None: super().__init__() self.ui_path = ui_path + self.cdn = cdn if cdn else self._default_cdn @abstractmethod def build_ui(self, options: UIOptions) -> None: @@ -33,8 +62,14 @@ def get_ui_handler(self) -> Callable[[Request], Response]: class SwaggerUIProvider(UIProvider): - def __init__(self, ui_path: str = "/docs") -> None: - super().__init__(ui_path) + _default_cdn = CdnOptions(SWAGGER_UI_CDN, SWAGGER_UI_CSS, SWAGGER_UI_FONT) + + def __init__( + self, + ui_path: str = "/docs", + cdn: Optional[CdnOptions] = None, + ) -> None: + super().__init__(ui_path, cdn) self._ui_html: bytes = b"" @@ -46,6 +81,8 @@ def get_openapi_ui_html(self, options: UIOptions) -> str: get_resource_file_content("swagger-ui.html") .replace("##SPEC_URL##", options.spec_url) .replace("##PAGE_TITLE##", options.page_title) + .replace("##JS_CDN##", self.cdn.js_cdn_url) + .replace("##CSS_CDN##", self.cdn.css_cdn_url) ) def build_ui(self, options: UIOptions) -> None: @@ -63,8 +100,12 @@ def get_open_api_ui(request: Request) -> Response: class ReDocUIProvider(UIProvider): - def __init__(self, ui_path: str = "/redocs") -> None: - super().__init__(ui_path) + _default_cdn = CdnOptions(REDOC_UI_CDN, REDOC_UI_CSS, REDOC_UI_FONT) + + def __init__( + self, ui_path: str = "/redocs", cdn: Optional[CdnOptions] = None + ) -> None: + super().__init__(ui_path, cdn) self._ui_html: bytes = b"" @@ -76,6 +117,8 @@ def get_openapi_ui_html(self, options: UIOptions) -> str: get_resource_file_content("redoc-ui.html") .replace("##SPEC_URL##", options.spec_url) .replace("##PAGE_TITLE##", options.page_title) + .replace("##JS_CDN##", self.cdn.js_cdn_url) + .replace("##FONT_CDN##", self.cdn.fontset_cdn_url) ) def build_ui(self, options: UIOptions) -> None: diff --git a/blacksheep/server/res/redoc-ui.html b/blacksheep/server/res/redoc-ui.html index 5d26bc7a..3736a0e7 100644 --- a/blacksheep/server/res/redoc-ui.html +++ b/blacksheep/server/res/redoc-ui.html @@ -5,7 +5,7 @@ - + + + + + + + +""".strip() + ) + + def test_open_api_json(session_2): response = session_2.get("/openapi.json") diff --git a/itests/utils.py b/itests/utils.py index 1244c1d2..e1e6fc4d 100644 --- a/itests/utils.py +++ b/itests/utils.py @@ -71,3 +71,7 @@ def get_sleep_time(): if os.name == "nt": return 1.5 return 0.5 + + +def foo_cdn(rsc: str): + return f"my-cdn-foo:{rsc}" From eb8e034b493baba44a3268e422bbb5b5c397af35 Mon Sep 17 00:00:00 2001 From: Roberto Prevato Date: Sun, 12 Nov 2023 20:24:19 +0100 Subject: [PATCH 3/8] Fix test assertion --- itests/test_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itests/test_server.py b/itests/test_server.py index 37609fd8..f358d798 100644 --- a/itests/test_server.py +++ b/itests/test_server.py @@ -475,7 +475,7 @@ def test_open_api_redoc_ui_custom_cdn(session_4): - +