From deb01e0f689ed6b21a45926acb0c17e7e5c9d22e Mon Sep 17 00:00:00 2001 From: Erwan Rouchet <rouchet@teklia.com> Date: Fri, 29 May 2020 12:52:56 +0000 Subject: [PATCH] Add ReDoc documentation --- arkindex/project/mixins.py | 16 ++++++++++++++++ arkindex/project/urls.py | 3 ++- arkindex/project/views.py | 21 ++++++++++++++------- arkindex/templates/redoc.html | 23 +++++++++++++++++++++++ 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 arkindex/templates/redoc.html diff --git a/arkindex/project/mixins.py b/arkindex/project/mixins.py index db62982097..5a26c9de65 100644 --- a/arkindex/project/mixins.py +++ b/arkindex/project/mixins.py @@ -1,6 +1,7 @@ from django.shortcuts import get_object_or_404 from django.conf import settings from django.core.exceptions import PermissionDenied +from django.views.decorators.cache import cache_page from rest_framework.exceptions import APIException, ValidationError from rest_framework.serializers import Serializer from arkindex.documents.models import Corpus, Right, Element @@ -144,3 +145,18 @@ class DeprecatedMixin(object): method = request.method.lower() if method in self.http_method_names and hasattr(self, method): raise DeprecatedAPIException(detail=getattr(self, 'deprecation_message', None)) + + +class CachedViewMixin(object): + """ + Add this mixin to any class-based view to cache it. + """ + cache_timeout = None + cache_prefix = None + + def __init__(self, *args, **kwargs): + if self.cache_timeout: + self.dispatch = cache_page( + self.cache_timeout, + key_prefix=self.cache_prefix, + )(self.dispatch) diff --git a/arkindex/project/urls.py b/arkindex/project/urls.py index 5ece3a876d..5e26e34ba4 100644 --- a/arkindex/project/urls.py +++ b/arkindex/project/urls.py @@ -3,13 +3,14 @@ from django.conf import settings from django.contrib import admin from django.contrib.staticfiles.urls import staticfiles_urlpatterns from arkindex.project.api_v1 import api -from arkindex.project.views import FrontendView, CdnHome +from arkindex.project.views import FrontendView, CdnHome, OpenAPIDocsView # Fallback to the dummy frontend view when CDN_ASSETS_URL is not set frontend_view = FrontendView if settings.CDN_ASSETS_URL is None else CdnHome urlpatterns = [ path('api/v1/', include((api, 'api'), namespace='api')), + path('api-docs/', OpenAPIDocsView.as_view(), name='openapi-docs'), path('ponos/', include('ponos.urls')), path('admin/', admin.site.urls), # Frontend URLs the backend needs with django.urls.reverse diff --git a/arkindex/project/views.py b/arkindex/project/views.py index 80604c466d..ddb94f2a13 100644 --- a/arkindex/project/views.py +++ b/arkindex/project/views.py @@ -1,6 +1,7 @@ from django.views.generic import View, TemplateView -from django.views.decorators.cache import cache_page from django.conf import settings +from arkindex.project.mixins import CachedViewMixin +import arkindex class FrontendView(View): @@ -10,16 +11,13 @@ class FrontendView(View): """ -class CdnHome(TemplateView): +class CdnHome(CachedViewMixin, TemplateView): """ Index template to use frontend assets from a CDN """ template_name = 'index.html' - - def dispatch(self, *args, **kwargs): - # Cache rendered page - # On dev, by default a dummy cache is enabled - return cache_page(60 * 10)(super().dispatch)(*args, **kwargs) + cache_timeout = 86400 + cache_prefix = settings.FRONTEND_VERSION def get_context_data(self, *args, **kwargs): ctx = super().get_context_data(*args, **kwargs) @@ -30,3 +28,12 @@ class CdnHome(TemplateView): ctx['frontend_version'] = settings.FRONTEND_VERSION ctx['frontend_sentry_dsn'] = settings.FRONTEND_SENTRY_DSN return ctx + + +class OpenAPIDocsView(CachedViewMixin, TemplateView): + """ + OpenAPI documentation via ReDoc + """ + template_name = 'redoc.html' + cache_timeout = 86400 + cache_prefix = arkindex.VERSION diff --git a/arkindex/templates/redoc.html b/arkindex/templates/redoc.html new file mode 100644 index 0000000000..1501bfdb9a --- /dev/null +++ b/arkindex/templates/redoc.html @@ -0,0 +1,23 @@ +{% load package_version %} +<!DOCTYPE html> +<html> + <head> + <title>Arkindex API {% package_version %}</title> + <!-- needed for adaptive design --> + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet"> + <!-- ReDoc doesn't change outer page styles --> + <style> + body { + margin: 0; + padding: 0; + } + </style> + </head> + <body> + <!-- Add ?format=openapi to make ReDoc's download button get a YAML file, not HTML --> + <redoc spec-url="{% url 'api:openapi-schema' %}?format=openapi"></redoc> + <script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script> + </body> +</html> -- GitLab