Skip to content

Commit

Permalink
feat(headless): Serve Redoc/Swagger
Browse files Browse the repository at this point in the history
  • Loading branch information
pennersr authored and pennersr committed Dec 27, 2024
1 parent 5d7b4bc commit ef53f0a
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 8 deletions.
7 changes: 5 additions & 2 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ Note worthy changes
compatible manner.

- Headless: when ``HEADLESS_SERVE_SPECIFICATION`` is set to ``True``, the API
specification will be served dynamically, over at ``/_allauth/openapi.yaml``,
``/_allauth/openapi.json`` and ``/_allauth/docs``.
specification will be served dynamically, over at
``/_allauth/openapi.(yaml|json|html)``. The
``HEADLESS_SPECIFICATION_TEMPLATE_NAME`` can be configured to choose between
Redoc (``"headless/spec/redoc_cdn.html"``) and Swagger (
(``"headless/spec/swagger_cdn.html"``).

- Headless: added a new setting, ``HEADLESS_CLIENTS`` which you can use to limit
the types of API clientsx (app/browser).
Expand Down
8 changes: 6 additions & 2 deletions allauth/headless/app_settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Tuple
from typing import Optional, Tuple


class AppSettings:
Expand Down Expand Up @@ -27,9 +27,13 @@ def TOKEN_STRATEGY(self):
return cls()

@property
def SERVE_SPECIFICATION(self):
def SERVE_SPECIFICATION(self) -> bool:
return self._setting("SERVE_SPECIFICATION", False)

@property
def SPECIFICATION_TEMPLATE_NAME(self) -> Optional[str]:
return "headless/spec/redoc_cdn.html"

@property
def CLIENTS(self) -> Tuple[str]:
return tuple(self._setting("CLIENTS", ("browser", "app")))
Expand Down
11 changes: 10 additions & 1 deletion allauth/headless/spec/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
from django.urls import path

from allauth.headless import app_settings
from allauth.headless.spec import views


urlpatterns = [
path("openapi.yaml", views.OpenAPIYAMLView.as_view(), name="openapi_yaml"),
path("openapi.json", views.OpenAPIJSONView.as_view(), name="openapi_json"),
path("docs", views.OpenAPIDocumentationView.as_view(), name="openapi_doc"),
]

if app_settings.SERVE_SPECIFICATION and app_settings.SPECIFICATION_TEMPLATE_NAME:
urlpatterns.append(
path(
"openapi.html",
views.OpenAPIHTMLView.as_view(),
name="openapi_html",
),
)
6 changes: 4 additions & 2 deletions allauth/headless/spec/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.http import HttpResponse
from django.views.generic import TemplateView, View

from allauth.headless import app_settings
from allauth.headless.spec.internal.schema import get_schema


Expand Down Expand Up @@ -30,5 +31,6 @@ def get(self, request):
)


class OpenAPIDocumentationView(TemplateView):
template_name = "headless/openapi.html"
class OpenAPIHTMLView(TemplateView):
def get_template_names(self):
return [app_settings.SPECIFICATION_TEMPLATE_NAME]
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<title>allauth.headless OpenAPI Specification | django-allauth</title>
</head>
<body>
<redoc spec-url="./openapi.json"></redoc>
<redoc spec-url="{% url 'headless:openapi_json' %}"></redoc>
<script src="//cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"> </script>
</body>
</html>
28 changes: 28 additions & 0 deletions allauth/headless/templates/headless/spec/swagger_cdn.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<link type="text/css"
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css">
<title>allauth.headless OpenAPI Specification | django-allauth</title>
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
<script>
const config = {
url: "{% url 'headless:openapi_json' %}",
dom_id: "#swagger-ui",
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
requestInterceptor: (req) => {
req.headers['X-CSRFToken'] = "{{csrf_token}}";
return req;
},
};
const ui = SwaggerUIBundle(config);
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions docs/headless/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ Available settings:
endpoints ``/_allauth/openapi.yaml``, ``/_allauth/openapi.json`` and
``/_allauth/docs`` become available.

``HEADLESS_SPECIFICATION_TEMPLATE_NAME`` (default: ``"headless/spec/redoc_cdn.html"``)
The template used to serve the OpenAPI specification in HTML format. Out of the box,
Redoc (``"headless/spec/redoc_cdn.html"``) and Swagger (
(``"headless/spec/swagger_cdn.html"``) are available..

``HEADLESS_TOKEN_STRATEGY`` (default: ``"allauth.headless.tokens.sessions.SessionTokenStrategy"``)
If you need to change the way tokens are created and handled, you can plug in your own
:doc:`./tokens`.

0 comments on commit ef53f0a

Please sign in to comment.