Skip to content

Commit

Permalink
Apply corrections before merge
Browse files Browse the repository at this point in the history
- Do not assume that URLs are for CDNs
- Remove the connection between OpenAPIHandler and class with files URLs
  • Loading branch information
RobertoPrevato committed Nov 17, 2023
1 parent 48ecd97 commit 7bf3178
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 53 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2.0a12] - 2023-11-?? :fallen_leaf:

- Adds support for Python 3.12, by @bymoye
- Adds support for custom files URLs for ReDoc and Swagger UI, by @joshua-auchincloss
- Replaces `pkg_resources` with `importlib.resources` for all supported Python
versions except for `3.8`.
- Runs tests against Pydantic `2.4.2` instead of Pydantic `2.0` to check
Expand Down
7 changes: 2 additions & 5 deletions blacksheep/server/openapi/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from blacksheep.server.routing import Route, Router
from blacksheep.utils.time import utcnow

from .ui import CdnOptions, SwaggerUIProvider, UIOptions, UIProvider
from .ui import SwaggerUIProvider, UIOptions, UIProvider

T = TypeVar("T")

Expand Down Expand Up @@ -167,7 +167,6 @@ def __init__(
yaml_spec_path: str = "/openapi.yaml",
preferred_format: Format = Format.JSON,
anonymous_access: bool = True,
swagger_ui_cdn: Optional[CdnOptions] = None,
) -> None:
self._handlers_docs: Dict[Any, EndpointDocs] = {}
self.use_docstrings: bool = True
Expand All @@ -178,9 +177,7 @@ def __init__(
self._yaml_docs: bytes = b""
self.preferred_format = preferred_format
self.anonymous_access = anonymous_access
self.ui_providers: List[UIProvider] = [
SwaggerUIProvider(ui_path, swagger_ui_cdn)
]
self.ui_providers: List[UIProvider] = [SwaggerUIProvider(ui_path)]
self._types_schemas = {}
self.events = OpenAPIEvents(self)
self.handle_optional_response_with_404 = True
Expand Down
52 changes: 27 additions & 25 deletions blacksheep/server/openapi/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,26 @@
from blacksheep.server.resources import get_resource_file_content
from blacksheep.utils.time import utcnow

SWAGGER_UI_CDN = (
SWAGGER_UI_JS_URL = (
"https://cdn.jsdelivr.net/npm/[email protected]/swagger-ui-bundle.js"
)
SWAGGER_UI_CSS = "https://cdn.jsdelivr.net/npm/[email protected]/swagger-ui.css"
SWAGGER_UI_CSS_URL = (
"https://cdn.jsdelivr.net/npm/[email protected]/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 = (
REDOC_UI_JS_URL = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"
REDOC_UI_CSS_URL = None
REDOC_UI_FONT_URL = (
"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
class UIFilesOptions:
js_url: str
css_url: Optional[str] = None
fonts_url: Optional[str] = None


@dataclass
Expand All @@ -34,17 +36,17 @@ class UIOptions:


class UIProvider(ABC):
cdn: CdnOptions
ui_files: UIFilesOptions
ui_path: str

def __init__(
self,
ui_path: str,
cdn: Optional[CdnOptions] = None,
ui_files: Optional[UIFilesOptions] = None,
) -> None:
super().__init__()
self.ui_path = ui_path
self.cdn = cdn if cdn else self.default_cdn
self.ui_files = ui_files if ui_files else self.default_ui_files

@abstractmethod
def build_ui(self, options: UIOptions) -> None:
Expand All @@ -59,17 +61,17 @@ def get_ui_handler(self) -> Callable[[Request], Response]:
"""

@property
def default_cdn(self) -> CdnOptions:
def default_ui_files(self) -> UIFilesOptions:
...


class SwaggerUIProvider(UIProvider):
def __init__(
self,
ui_path: str = "/docs",
cdn: Optional[CdnOptions] = None,
ui_files_options: Optional[UIFilesOptions] = None,
) -> None:
super().__init__(ui_path, cdn)
super().__init__(ui_path, ui_files_options)

self._ui_html: bytes = b""

Expand All @@ -81,8 +83,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)
.replace("##JS_URL##", self.ui_files.js_url)
.replace("##CSS_URL##", self.ui_files.css_url or "")
)

def build_ui(self, options: UIOptions) -> None:
Expand All @@ -99,15 +101,15 @@ def get_open_api_ui(request: Request) -> Response:
return get_open_api_ui

@property
def default_cdn(self) -> CdnOptions:
return CdnOptions(SWAGGER_UI_CDN, SWAGGER_UI_CSS, SWAGGER_UI_FONT)
def default_ui_files(self) -> UIFilesOptions:
return UIFilesOptions(SWAGGER_UI_JS_URL, SWAGGER_UI_CSS_URL, SWAGGER_UI_FONT)


class ReDocUIProvider(UIProvider):
def __init__(
self, ui_path: str = "/redocs", cdn: Optional[CdnOptions] = None
self, ui_path: str = "/redocs", ui_files: Optional[UIFilesOptions] = None
) -> None:
super().__init__(ui_path, cdn)
super().__init__(ui_path, ui_files)

self._ui_html: bytes = b""

Expand All @@ -119,8 +121,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)
.replace("##JS_URL##", self.ui_files.js_url)
.replace("##FONT_URL##", self.ui_files.fonts_url or "")
)

def build_ui(self, options: UIOptions) -> None:
Expand All @@ -137,5 +139,5 @@ def get_open_api_ui(request: Request) -> Response:
return get_open_api_ui

@property
def default_cdn(self) -> CdnOptions:
return CdnOptions(REDOC_UI_CDN, REDOC_UI_CSS, REDOC_UI_FONT)
def default_ui_files(self) -> UIFilesOptions:
return UIFilesOptions(REDOC_UI_JS_URL, REDOC_UI_CSS_URL, REDOC_UI_FONT_URL)
3 changes: 0 additions & 3 deletions blacksheep/server/openapi/v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
ResponseStatusType,
response_status_to_str,
)
from .ui import CdnOptions

try:
from pydantic import BaseModel # type: ignore
Expand Down Expand Up @@ -377,15 +376,13 @@ def __init__(
SecuritySchemes,
]
] = None,
swagger_ui_cdn: Optional[CdnOptions] = None,
) -> None:
super().__init__(
ui_path=ui_path,
json_spec_path=json_spec_path,
yaml_spec_path=yaml_spec_path,
preferred_format=preferred_format,
anonymous_access=anonymous_access,
swagger_ui_cdn=swagger_ui_cdn,
)
self.info = info
self._tags = tags
Expand Down
4 changes: 2 additions & 2 deletions blacksheep/server/res/redoc-ui.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/favicon.png"/>
<link href="##FONT_CDN##" rel="stylesheet">
<link href="##FONT_URL##" rel="stylesheet">
<style>
body {
margin: 0;
Expand All @@ -15,6 +15,6 @@
</head>
<body>
<redoc spec-url="##SPEC_URL##"></redoc>
<script src="##JS_CDN##"> </script>
<script src="##JS_URL##"> </script>
</body>
</html>
4 changes: 2 additions & 2 deletions blacksheep/server/res/swagger-ui.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
<head>
<title>##PAGE_TITLE##</title>
<link rel="icon" href="/favicon.png"/>
<link type="text/css" rel="stylesheet" href="##CSS_CDN##">
<link type="text/css" rel="stylesheet" href="##CSS_URL##">
</head>
<body>
<div id="swagger-ui"></div>
<script src="##JS_CDN##"></script>
<script src="##JS_URL##"></script>
<script>
const ui = SwaggerUIBundle({
url: '##SPEC_URL##',
Expand Down
18 changes: 9 additions & 9 deletions itests/app_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
from blacksheep.server import Application
from blacksheep.server.bindings import FromJSON
from blacksheep.server.compression import use_gzip_compression
from blacksheep.server.openapi.ui import CdnOptions, ReDocUIProvider
from blacksheep.server.openapi.ui import ReDocUIProvider, UIFilesOptions
from blacksheep.server.openapi.v3 import OpenAPIHandler
from blacksheep.server.responses import json
from blacksheep.server.websocket import WebSocket
from blacksheep.settings.json import default_json_dumps, json_settings

from .utils import foo_cdn
from .utils import get_test_files_url

SINGLE_PID = None

Expand Down Expand Up @@ -155,16 +155,16 @@ async def echo_json(websocket: WebSocket):
await websocket.send_json(msg)


docs = OpenAPIHandler(
info=Info(title="Cats API", version="0.0.1"),
swagger_ui_cdn=CdnOptions(
js_cdn_url=foo_cdn("swag-js"), css_cdn_url=foo_cdn("swag-css")
),
docs = OpenAPIHandler(info=Info(title="Cats API", version="0.0.1"))
docs.ui_providers[0].ui_files = UIFilesOptions(
js_url=get_test_files_url("swag-js"),
css_url=get_test_files_url("swag-css"),
)
docs.ui_providers.append(
ReDocUIProvider(
cdn=CdnOptions(
js_cdn_url=foo_cdn("redoc-js"), fontset_cdn_url=foo_cdn("redoc-fonts")
ui_files=UIFilesOptions(
js_url=get_test_files_url("redoc-js"),
fonts_url=get_test_files_url("redoc-fonts"),
)
)
)
Expand Down
10 changes: 5 additions & 5 deletions itests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from .client_fixtures import get_static_path
from .server_fixtures import * # NoQA
from .utils import assert_files_equals, ensure_success, foo_cdn
from .utils import assert_files_equals, ensure_success, get_test_files_url


def test_hello_world(session_1):
Expand Down Expand Up @@ -434,11 +434,11 @@ def test_open_api_ui_custom_cdn(session_4):
<head>
<title>Cats API</title>
<link rel="icon" href="/favicon.png"/>
<link type="text/css" rel="stylesheet" href="{foo_cdn("swag-css")}">
<link type="text/css" rel="stylesheet" href="{get_test_files_url("swag-css")}">
</head>
<body>
<div id="swagger-ui"></div>
<script src="{foo_cdn("swag-js")}"></script>
<script src="{get_test_files_url("swag-js")}"></script>
<script>
const ui = SwaggerUIBundle({{
url: '/openapi.json',
Expand Down Expand Up @@ -475,7 +475,7 @@ def test_open_api_redoc_ui_custom_cdn(session_4):
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/favicon.png"/>
<link href="{foo_cdn("redoc-fonts")}" rel="stylesheet">
<link href="{get_test_files_url("redoc-fonts")}" rel="stylesheet">
<style>
body {{
margin: 0;
Expand All @@ -485,7 +485,7 @@ def test_open_api_redoc_ui_custom_cdn(session_4):
</head>
<body>
<redoc spec-url="/openapi.json"></redoc>
<script src="{foo_cdn("redoc-js")}"> </script>
<script src="{get_test_files_url("redoc-js")}"> </script>
</body>
</html>
""".strip()
Expand Down
4 changes: 2 additions & 2 deletions itests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,5 @@ def get_sleep_time():
return 0.5


def foo_cdn(rsc: str):
return f"my-cdn-foo:{rsc}"
def get_test_files_url(url: str):
return f"my-cdn-foo:{url}"

0 comments on commit 7bf3178

Please sign in to comment.