Add SPEC_URL setting

openapi3
Cristi Vîjdea 2018-08-09 03:32:04 +03:00
parent 8a69f08c29
commit cd4bd4a18e
5 changed files with 102 additions and 38 deletions

View File

@ -31,12 +31,23 @@ Example:
... ...
} }
.. _url-settings:
All settings which configure URLs (``LOGIN_URL``, ``SPEC_URL``, ``VALIDATOR_URL``, etc.) can accept several forms of
input:
* A view name: `urls.reverse()` will be used to reverse-resolve the name
* A 2-tuple of ``(view_name, kwargs)```: `urls.reverse()` will be used to reverse-resolve the name using the given
`kwargs`; `kwargs` must be a dict
* A 3-tuple of ``(view_name, args, kwargs)```: `urls.reverse()` will be used to reverse-resolve the name using the given
`args` and `kwargs`; `args`, `kwargs` must be a tuple/list and a dict respectively
* A URL, which will be used as-is
The possible settings and their default values are as follows: The possible settings and their default values are as follows:
******************** ****************
``SWAGGER_SETTINGS`` SWAGGER_SETTINGS
******************** ****************
.. _default-class-settings: .. _default-class-settings:
@ -192,6 +203,15 @@ Swagger UI settings
Swagger UI configuration settings. |br| Swagger UI configuration settings. |br|
See https://github.com/swagger-api/swagger-ui/blob/112bca906553a937ac67adc2e500bdeed96d067b/docs/usage/configuration.md#parameters. See https://github.com/swagger-api/swagger-ui/blob/112bca906553a937ac67adc2e500bdeed96d067b/docs/usage/configuration.md#parameters.
SPEC_URL
--------
URL pointing to a swagger document for use by swagger-ui. The default behaviour is to append ``?format=openapi`` to the
URL which serves the UI; see :ref:`note on URL settings <url-settings>` above.
**Default**: :python:`None` |br|
*Maps to parameter*: ``url``
VALIDATOR_URL VALIDATOR_URL
------------- -------------
@ -312,9 +332,9 @@ This does not filter the operations from the display.
**Default**: :python:`['get','put','post','delete','options','head','patch','trace']` |br| **Default**: :python:`['get','put','post','delete','options','head','patch','trace']` |br|
*Maps to parameter*: ``supportedSubmitMethods`` *Maps to parameter*: ``supportedSubmitMethods``
****************** **************
``REDOC_SETTINGS`` REDOC_SETTINGS
****************** **************
.. _redoc-ui-settings: .. _redoc-ui-settings:
@ -324,6 +344,15 @@ ReDoc UI settings
ReDoc UI configuration settings. |br| ReDoc UI configuration settings. |br|
See https://github.com/Rebilly/ReDoc#configuration. See https://github.com/Rebilly/ReDoc#configuration.
SPEC_URL
--------
URL pointing to a swagger document for use by ReDoc. The default behaviour is to append ``?format=openapi`` to the
URL which serves the UI; see :ref:`note on URL settings <url-settings>` above.
**Default**: :python:`None` |br|
*Maps to attribute*: ``spec-url``
LAZY_RENDERING LAZY_RENDERING
-------------- --------------

View File

@ -40,6 +40,7 @@ SWAGGER_DEFAULTS = {
'SECURITY_REQUIREMENTS': None, 'SECURITY_REQUIREMENTS': None,
'LOGIN_URL': getattr(settings, 'LOGIN_URL', None), 'LOGIN_URL': getattr(settings, 'LOGIN_URL', None),
'LOGOUT_URL': getattr(settings, 'LOGOUT_URL', None), 'LOGOUT_URL': getattr(settings, 'LOGOUT_URL', None),
'SPEC_URL': None,
'VALIDATOR_URL': '', 'VALIDATOR_URL': '',
'OPERATIONS_SORTER': None, 'OPERATIONS_SORTER': None,
@ -65,6 +66,7 @@ SWAGGER_DEFAULTS = {
} }
REDOC_DEFAULTS = { REDOC_DEFAULTS = {
'SPEC_URL': None,
'LAZY_RENDERING': True, 'LAZY_RENDERING': True,
'HIDE_HOSTNAME': False, 'HIDE_HOSTNAME': False,
'EXPAND_RESPONSES': 'all', 'EXPAND_RESPONSES': 'all',

View File

@ -1,8 +1,11 @@
import six
from django.shortcuts import render, resolve_url from django.shortcuts import render, resolve_url
from rest_framework.renderers import BaseRenderer, JSONRenderer, TemplateHTMLRenderer from rest_framework.renderers import BaseRenderer, JSONRenderer, TemplateHTMLRenderer
from rest_framework.utils import json from rest_framework.utils import json
from drf_yasg.openapi import Swagger from drf_yasg.openapi import Swagger
from drf_yasg.utils import filter_none
from .app_settings import redoc_settings, swagger_settings from .app_settings import redoc_settings, swagger_settings
from .codecs import VALIDATORS, OpenAPICodecJson, OpenAPICodecYaml from .codecs import VALIDATORS, OpenAPICodecJson, OpenAPICodecYaml
@ -74,23 +77,52 @@ class _UIRenderer(BaseRenderer):
def set_context(self, renderer_context, swagger): def set_context(self, renderer_context, swagger):
renderer_context['title'] = swagger.info.title renderer_context['title'] = swagger.info.title
renderer_context['version'] = swagger.info.version renderer_context['version'] = swagger.info.version
renderer_context['swagger_settings'] = json.dumps(self.get_swagger_ui_settings())
renderer_context['redoc_settings'] = json.dumps(self.get_redoc_settings())
renderer_context['oauth2_config'] = json.dumps(self.get_oauth2_config()) renderer_context['oauth2_config'] = json.dumps(self.get_oauth2_config())
renderer_context['USE_SESSION_AUTH'] = swagger_settings.USE_SESSION_AUTH renderer_context['USE_SESSION_AUTH'] = swagger_settings.USE_SESSION_AUTH
renderer_context.update(self.get_auth_urls()) renderer_context.update(self.get_auth_urls())
def get_auth_urls(self): def resolve_url(self, to):
urls = {} if to is None:
if swagger_settings.LOGIN_URL is not None: return None
urls['LOGIN_URL'] = resolve_url(swagger_settings.LOGIN_URL)
if swagger_settings.LOGOUT_URL is not None:
urls['LOGOUT_URL'] = resolve_url(swagger_settings.LOGOUT_URL)
return urls args, kwargs = None, None
if not isinstance(to, six.string_types):
if len(to) > 2:
to, args, kwargs = to
elif len(to) == 2:
to, kwargs = to
args = args or ()
kwargs = kwargs or {}
return resolve_url(to, *args, **kwargs)
def get_auth_urls(self):
urls = {
'LOGIN_URL': self.resolve_url(swagger_settings.LOGIN_URL),
'LOGOUT_URL': self.resolve_url(swagger_settings.LOGOUT_URL),
}
return filter_none(urls)
def get_oauth2_config(self):
data = swagger_settings.OAUTH2_CONFIG
assert isinstance(data, dict), "OAUTH2_CONFIG must be a dict"
return data
class SwaggerUIRenderer(_UIRenderer):
"""Renders a swagger-ui web interface for schema browisng."""
template = 'drf-yasg/swagger-ui.html'
format = 'swagger'
def set_context(self, renderer_context, swagger):
super(SwaggerUIRenderer, self).set_context(renderer_context, swagger)
renderer_context['swagger_settings'] = json.dumps(self.get_swagger_ui_settings())
def get_swagger_ui_settings(self): def get_swagger_ui_settings(self):
data = { data = {
'url': self.resolve_url(swagger_settings.SPEC_URL),
'operationsSorter': swagger_settings.OPERATIONS_SORTER, 'operationsSorter': swagger_settings.OPERATIONS_SORTER,
'tagsSorter': swagger_settings.TAGS_SORTER, 'tagsSorter': swagger_settings.TAGS_SORTER,
'docExpansion': swagger_settings.DOC_EXPANSION, 'docExpansion': swagger_settings.DOC_EXPANSION,
@ -103,42 +135,35 @@ class _UIRenderer(BaseRenderer):
'oauth2RedirectUrl': swagger_settings.OAUTH2_REDIRECT_URL, 'oauth2RedirectUrl': swagger_settings.OAUTH2_REDIRECT_URL,
'supportedSubmitMethods': swagger_settings.SUPPORTED_SUBMIT_METHODS, 'supportedSubmitMethods': swagger_settings.SUPPORTED_SUBMIT_METHODS,
} }
data = {k: v for k, v in data.items() if v is not None} data = filter_none(data)
if swagger_settings.VALIDATOR_URL != '': if swagger_settings.VALIDATOR_URL != '':
data['validatorUrl'] = swagger_settings.VALIDATOR_URL data['validatorUrl'] = self.resolve_url(swagger_settings.VALIDATOR_URL)
return data return data
class ReDocRenderer(_UIRenderer):
"""Renders a ReDoc web interface for schema browisng."""
template = 'drf-yasg/redoc.html'
format = 'redoc'
def set_context(self, renderer_context, swagger):
super(ReDocRenderer, self).set_context(renderer_context, swagger)
renderer_context['redoc_settings'] = json.dumps(self.get_redoc_settings())
def get_redoc_settings(self): def get_redoc_settings(self):
data = { data = {
'url': self.resolve_url(redoc_settings.SPEC_URL),
'lazyRendering': redoc_settings.LAZY_RENDERING, 'lazyRendering': redoc_settings.LAZY_RENDERING,
'hideHostname': redoc_settings.HIDE_HOSTNAME, 'hideHostname': redoc_settings.HIDE_HOSTNAME,
'expandResponses': redoc_settings.EXPAND_RESPONSES, 'expandResponses': redoc_settings.EXPAND_RESPONSES,
'pathInMiddle': redoc_settings.PATH_IN_MIDDLE, 'pathInMiddle': redoc_settings.PATH_IN_MIDDLE,
} }
data = filter_none(data)
return data return data
def get_oauth2_config(self):
data = swagger_settings.OAUTH2_CONFIG
assert isinstance(data, dict), "OAUTH2_CONFIG must be a dict"
return data
class SwaggerUIRenderer(_UIRenderer):
"""Renders a swagger-ui web interface for schema browisng.
Also requires :class:`.OpenAPIRenderer` as an available renderer on the same view.
"""
template = 'drf-yasg/swagger-ui.html'
format = 'swagger'
class ReDocRenderer(_UIRenderer):
"""Renders a ReDoc web interface for schema browisng.
Also requires :class:`.OpenAPIRenderer` as an available renderer on the same view.
"""
template = 'drf-yasg/redoc.html'
format = 'redoc'
class ReDocOldRenderer(ReDocRenderer): class ReDocOldRenderer(ReDocRenderer):
"""Renders a ReDoc 1.x.x web interface for schema browisng.""" """Renders a ReDoc 1.x.x web interface for schema browisng."""
template = 'drf-yasg/redoc-old.html' template = 'drf-yasg/redoc-old.html'

View File

@ -3,9 +3,13 @@
var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname; var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname;
var specURL = currentPath + '?format=openapi'; var specURL = currentPath + '?format=openapi';
var redoc = document.createElement("redoc"); var redoc = document.createElement("redoc");
redoc.setAttribute("spec-url", specURL);
var redocSettings = JSON.parse(document.getElementById('redoc-settings').innerHTML); var redocSettings = JSON.parse(document.getElementById('redoc-settings').innerHTML);
if (redocSettings.url) {
specURL = redocSettings.url;
}
redoc.setAttribute("spec-url", specURL);
if (redocSettings.lazyRendering) { if (redocSettings.lazyRendering) {
redoc.setAttribute("lazy-rendering", ''); redoc.setAttribute("lazy-rendering", '');
} }

View File

@ -108,6 +108,10 @@ SWAGGER_SETTINGS = {
} }
} }
REDOC_SETTINGS = {
'SPEC_URL': ('schema-json', {'format': '.json'}),
}
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/ # https://docs.djangoproject.com/en/1.11/topics/i18n/