Skip to content

Commit

Permalink
refactor: expose cdn opts
Browse files Browse the repository at this point in the history
- added tests
  • Loading branch information
joshua-auchincloss committed Oct 18, 2023
1 parent 2cd9d7b commit 1fb49b0
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 10 deletions.
7 changes: 5 additions & 2 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.files.static import get_response_for_static_content
from blacksheep.server.routing import Route, Router

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

T = TypeVar("T")

Expand Down Expand Up @@ -167,6 +167,7 @@ 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 @@ -177,7 +178,9 @@ 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)]
self.ui_providers: List[UIProvider] = [
SwaggerUIProvider(ui_path, swagger_ui_cdn)
]
self._types_schemas = {}
self.events = OpenAPIEvents(self)
self.handle_optional_response_with_404 = True
Expand Down
20 changes: 13 additions & 7 deletions blacksheep/server/openapi/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,14 @@ class UIProvider(ABC):
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
self.cdn = cdn if cdn else self.default_cdn

@abstractmethod
def build_ui(self, options: UIOptions) -> None:
Expand All @@ -60,10 +58,12 @@ def get_ui_handler(self) -> Callable[[Request], Response]:
Returns a request handler for the route that serves a UI.
"""

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

class SwaggerUIProvider(UIProvider):
_default_cdn = CdnOptions(SWAGGER_UI_CDN, SWAGGER_UI_CSS, SWAGGER_UI_FONT)

class SwaggerUIProvider(UIProvider):
def __init__(
self,
ui_path: str = "/docs",
Expand Down Expand Up @@ -98,10 +98,12 @@ 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)

class ReDocUIProvider(UIProvider):
_default_cdn = CdnOptions(REDOC_UI_CDN, REDOC_UI_CSS, REDOC_UI_FONT)

class ReDocUIProvider(UIProvider):
def __init__(
self, ui_path: str = "/redocs", cdn: Optional[CdnOptions] = None
) -> None:
Expand Down Expand Up @@ -133,3 +135,7 @@ 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)
3 changes: 3 additions & 0 deletions blacksheep/server/openapi/v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
ResponseStatusType,
response_status_to_str,
)
from .ui import CdnOptions

try:
from pydantic import BaseModel # type: ignore
Expand Down Expand Up @@ -376,13 +377,15 @@ 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
20 changes: 20 additions & 0 deletions itests/app_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@
from datetime import datetime

import uvicorn
from openapidocs.v3 import Info

from blacksheep import JSONContent, Response
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.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

SINGLE_PID = None


Expand Down Expand Up @@ -150,6 +155,21 @@ 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.ui_providers.append(
ReDocUIProvider(
cdn=CdnOptions(
js_cdn_url=foo_cdn("redoc-js"), fontset_cdn_url=foo_cdn("redoc-fonts")
)
)
)
docs.bind_app(app_4)

if __name__ == "__main__":
configure_json_settings()
uvicorn.run(app_4, host="127.0.0.1", port=44557, log_level="debug")
73 changes: 72 additions & 1 deletion 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
from .utils import assert_files_equals, ensure_success, foo_cdn


def test_hello_world(session_1):
Expand Down Expand Up @@ -421,6 +421,77 @@ def test_open_api_redoc_ui(session_2):
)


def test_open_api_ui_custom_cdn(session_4):
response = session_4.get("/docs")

assert response.status_code == 200
text = response.text
assert (
text.strip()
== f"""
<!DOCTYPE html>
<html>
<head>
<title>Cats API</title>
<link rel="icon" href="/favicon.png"/>
<link type="text/css" rel="stylesheet" href="{foo_cdn("swag-css")}">
</head>
<body>
<div id="swagger-ui"></div>
<script src="{foo_cdn("swag-js")}"></script>
<script>
const ui = SwaggerUIBundle({{
url: '/openapi.json',
oauth2RedirectUrl: window.location.origin + '/docs/oauth2-redirect',
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "BaseLayout",
deepLinking: true,
showExtensions: true,
showCommonExtensions: true
}})
</script>
</body>
</html>
""".strip()
)


def test_open_api_redoc_ui_custom_cdn(session_4):
response = session_4.get("/redocs")

assert response.status_code == 200
text = response.text
assert (
text.strip()
== f"""
<!DOCTYPE html>
<html>
<head>
<title>Cats API</title>
<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-font")}" rel="stylesheet">
<style>
body {{
margin: 0;
padding: 0;
}}
</style>
</head>
<body>
<redoc spec-url="/openapi.json"></redoc>
<script src="{foo_cdn("redoc-js")}"> </script>
</body>
</html>
""".strip()
)


def test_open_api_json(session_2):
response = session_2.get("/openapi.json")

Expand Down
4 changes: 4 additions & 0 deletions itests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}"

0 comments on commit 1fb49b0

Please sign in to comment.