Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 68b0dda0b9 | |||
| f81795d745 | |||
| caa397b906 | |||
| faf81e7b6d | |||
| 74fcd47047 | |||
| 02b72c466e | |||
| 10deea826d | |||
| bbdc37a45e |
+2
-2
@@ -1,4 +1,6 @@
|
||||
node_modules/
|
||||
testproj/db.sqlite3
|
||||
.vscode/
|
||||
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Python template
|
||||
@@ -156,5 +158,3 @@ com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
testproj/db\.sqlite3
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ You want to contribute some code? Great! Here are a few steps to get you started
|
||||
$ virtualenv venv
|
||||
$ source venv/bin/activate
|
||||
(venv) $ pip install -e .[validation]
|
||||
(venv) $ pip install -rrequirements/dev.txt -rrequirements/test.txt
|
||||
(venv) $ pip install -rrequirements/dev.txt -rrequirements/test.txt "Django>=1.11.7"
|
||||
|
||||
#. **Make your changes and check them against the test project**
|
||||
|
||||
@@ -44,7 +44,7 @@ You want to contribute some code? Great! Here are a few steps to get you started
|
||||
|
||||
(venv) $ cd testproj
|
||||
(venv) $ python manage.py migrate
|
||||
(venv) $ cat createsuperuser.py | python manage.py shell
|
||||
(venv) $ python manage.py shell -c "import createsuperuser"
|
||||
(venv) $ python manage.py runserver
|
||||
(venv) $ firefox localhost:8000/swagger/
|
||||
|
||||
|
||||
+55
-35
@@ -29,12 +29,12 @@ Features
|
||||
- customization hooks at all points in the spec generation process
|
||||
- JSON and YAML format for spec
|
||||
- bundles latest version of
|
||||
`swagger-ui <https://github.com/swagger-api/swagger-ui>`__ and
|
||||
`redoc <https://github.com/Rebilly/ReDoc>`__ for viewing the generated documentation
|
||||
`swagger-ui <https://github.com/swagger-api/swagger-ui>`_ and
|
||||
`redoc <https://github.com/Rebilly/ReDoc>`_ for viewing the generated documentation
|
||||
- schema view is cacheable out of the box
|
||||
- generated Swagger schema can be automatically validated by
|
||||
`swagger-spec-validator <https://github.com/Yelp/swagger_spec_validator>`__ or
|
||||
`flex <https://github.com/pipermerriam/flex>`__
|
||||
`swagger-spec-validator <https://github.com/Yelp/swagger_spec_validator>`_ or
|
||||
`flex <https://github.com/pipermerriam/flex>`_
|
||||
|
||||
.. figure:: https://raw.githubusercontent.com/axnsan12/drf-yasg/1.0.2/screenshots/redoc-nested-response.png
|
||||
:width: 100%
|
||||
@@ -94,42 +94,42 @@ In ``settings.py``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
INSTALLED_APPS = [
|
||||
...
|
||||
'drf_yasg',
|
||||
...
|
||||
]
|
||||
INSTALLED_APPS = [
|
||||
...
|
||||
'drf_yasg',
|
||||
...
|
||||
]
|
||||
|
||||
In ``urls.py``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
...
|
||||
from drf_yasg.views import get_schema_view
|
||||
from drf_yasg import openapi
|
||||
...
|
||||
from drf_yasg.views import get_schema_view
|
||||
from drf_yasg import openapi
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
schema_view = get_schema_view(
|
||||
openapi.Info(
|
||||
title="Snippets API",
|
||||
default_version='v1',
|
||||
description="Test description",
|
||||
terms_of_service="https://www.google.com/policies/terms/",
|
||||
contact=openapi.Contact(email="contact@snippets.local"),
|
||||
license=openapi.License(name="BSD License"),
|
||||
),
|
||||
validators=['ssv', 'flex'],
|
||||
public=True,
|
||||
permission_classes=(permissions.AllowAny,),
|
||||
)
|
||||
schema_view = get_schema_view(
|
||||
openapi.Info(
|
||||
title="Snippets API",
|
||||
default_version='v1',
|
||||
description="Test description",
|
||||
terms_of_service="https://www.google.com/policies/terms/",
|
||||
contact=openapi.Contact(email="contact@snippets.local"),
|
||||
license=openapi.License(name="BSD License"),
|
||||
),
|
||||
validators=['ssv', 'flex'],
|
||||
public=True,
|
||||
permission_classes=(permissions.AllowAny,),
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^swagger(?P<format>.json|.yaml)$', schema_view.without_ui(cache_timeout=None), name='schema-json'),
|
||||
url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=None), name='schema-swagger-ui'),
|
||||
url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=None), name='schema-redoc'),
|
||||
...
|
||||
]
|
||||
urlpatterns = [
|
||||
url(r'^swagger(?P<format>.json|.yaml)$', schema_view.without_ui(cache_timeout=None), name='schema-json'),
|
||||
url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=None), name='schema-swagger-ui'),
|
||||
url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=None), name='schema-redoc'),
|
||||
...
|
||||
]
|
||||
|
||||
This exposes 4 cached, validated and publicly available endpoints:
|
||||
|
||||
@@ -251,9 +251,9 @@ caching the schema view in-memory, with some sane defaults:
|
||||
* caching is enabled by the `cache_page <https://docs.djangoproject.com/en/1.11/topics/cache/#the-per-view-cache>`__
|
||||
decorator, using the default Django cache backend, can be changed using the ``cache_kwargs`` argument
|
||||
* HTTP caching of the response is blocked to avoid confusing situations caused by being shown stale schemas
|
||||
* if `public` is set to ``False`` on the SchemaView, the cached schema varies on the ``Cookie`` and ``Authorization``
|
||||
HTTP headers to enable filtering of visible endpoints according to the authentication credentials of each user; note
|
||||
that this means that every user accessing the schema will have a separate schema cached in memory.
|
||||
* the cached schema varies on the ``Cookie`` and ``Authorization`` HTTP headers to enable filtering of visible endpoints
|
||||
according to the authentication credentials of each user; note that this means that every user accessing the schema
|
||||
will have a separate schema cached in memory.
|
||||
|
||||
4. Validation
|
||||
=============
|
||||
@@ -334,6 +334,26 @@ You can use the specification outputted by this library together with
|
||||
|
||||
See the github page linked above for more details.
|
||||
|
||||
.. _readme-testproj:
|
||||
|
||||
6. Example project
|
||||
==================
|
||||
|
||||
For additional usage examples, you can take a look at the test project in the ``testproj`` directory:
|
||||
|
||||
.. code:: console
|
||||
|
||||
$ git clone https://github.com/axnsan12/drf-yasg.git
|
||||
$ cd drf-yasg
|
||||
$ virtualenv venv
|
||||
$ source venv/bin/activate
|
||||
(venv) $ cd testproj
|
||||
(venv) $ pip install -r requirements.txt
|
||||
(venv) $ python manage.py migrate
|
||||
(venv) $ python manage.py shell -c "import createsuperuser"
|
||||
(venv) $ python manage.py runserver
|
||||
(venv) $ firefox localhost:8000/swagger/
|
||||
|
||||
**********
|
||||
Background
|
||||
**********
|
||||
|
||||
@@ -3,6 +3,21 @@ Changelog
|
||||
#########
|
||||
|
||||
|
||||
*********
|
||||
**1.1.3**
|
||||
*********
|
||||
|
||||
- **FIXED:** schema view cache will now always ``Vary`` on the ``Cookie`` and ``Authentication`` (the
|
||||
``Vary`` header was previously only added if ``public`` was set to ``True``) - this fixes issues related to Django
|
||||
authentication in ``swagger-ui`` and ``CurrentUserDefault`` values in the schema
|
||||
|
||||
*********
|
||||
**1.1.2**
|
||||
*********
|
||||
|
||||
- **IMPROVED:** updated ``swagger-ui`` to version 3.8.1
|
||||
- **IMPROVED:** removed some unneeded static files
|
||||
|
||||
*********
|
||||
**1.1.1**
|
||||
*********
|
||||
|
||||
@@ -199,8 +199,6 @@ nitpick_ignore = [
|
||||
('py:obj', 'APIView'),
|
||||
]
|
||||
|
||||
# TODO: inheritance aliases in sphinx 1.7
|
||||
|
||||
# even though the package should be already installed, the sphinx build on RTD
|
||||
# for some reason needs the sources dir to be in the path in order for viewcode to work
|
||||
sys.path.insert(0, os.path.abspath('../src'))
|
||||
|
||||
@@ -58,3 +58,30 @@ See the command help for more advanced options:
|
||||
usage: manage.py generate_swagger [-h] [--version] [-v {0,1,2,3}]
|
||||
... more options ...
|
||||
|
||||
|
||||
.. Note::
|
||||
|
||||
The :ref:`DEFAULT_INFO <default-swagger-settings>` setting must be defined when using the ``generate_swagger``
|
||||
command. For example, the :ref:`README quickstart <readme-quickstart>` code could be modified as such:
|
||||
|
||||
In ``settings.py``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
SWAGGER_SETTINGS = {
|
||||
'DEFAULT_INFO': 'import.path.to.urls.api_info',
|
||||
}
|
||||
|
||||
In ``urls.py``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
api_info = openapi.Info(
|
||||
title="Snippets API",
|
||||
... other arguments ...
|
||||
)
|
||||
|
||||
schema_view = get_schema_view(
|
||||
# the info argument is no longer needed here as it will be picked up from DEFAULT_INFO
|
||||
... other arguments ...
|
||||
)
|
||||
|
||||
@@ -94,6 +94,8 @@ Paginator inspectors given to :func:`@swagger_auto_schema <.swagger_auto_schema>
|
||||
Swagger document attributes
|
||||
===========================
|
||||
|
||||
.. _default-swagger-settings:
|
||||
|
||||
DEFAULT_INFO
|
||||
------------
|
||||
|
||||
|
||||
Generated
+3
-3
@@ -312,9 +312,9 @@
|
||||
}
|
||||
},
|
||||
"swagger-ui-dist": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.8.0.tgz",
|
||||
"integrity": "sha1-BHfLOagE7a6Wx+COskDNWagEt3U="
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.8.1.tgz",
|
||||
"integrity": "sha1-jzVrkwjZl3oJ1eQYGvdCAHPtzdk="
|
||||
},
|
||||
"tiny-emitter": {
|
||||
"version": "2.0.2",
|
||||
|
||||
+1
-1
@@ -2,6 +2,6 @@
|
||||
"name": "drf-yasg",
|
||||
"dependencies": {
|
||||
"redoc": "^1.19.3",
|
||||
"swagger-ui-dist": "^3.8.0"
|
||||
"swagger-ui-dist": "^3.8.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,5 +7,4 @@ isort>=4.2
|
||||
flake8>=3.5.0
|
||||
flake8-isort>=2.3
|
||||
|
||||
# do not unpin this (see setup.py)
|
||||
setuptools_scm==1.15.6
|
||||
-r setup.txt
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# requirements for building the distributable package
|
||||
|
||||
# do not unpin this (see setup.py)
|
||||
setuptools_scm==1.15.6
|
||||
@@ -6,10 +6,4 @@ pytest-cov>=2.5.1
|
||||
git+https://github.com/pytest-dev/pytest-django.git@94cccb956435dd7a719606744ee7608397e1eafb
|
||||
datadiff==2.0.0
|
||||
|
||||
# test project requirements
|
||||
Pillow>=4.3.0
|
||||
pygments>=2.2.0
|
||||
django-cors-headers>=2.1.0
|
||||
django-filter>=1.1.0,<2.0; python_version == "2.7"
|
||||
django-filter>=1.1.0; python_version >= "3.4"
|
||||
djangorestframework-camel-case>=0.2.0
|
||||
-r testproj.txt
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# test project requirements
|
||||
Pillow>=4.3.0
|
||||
pygments>=2.2.0
|
||||
django-cors-headers>=2.1.0
|
||||
django-filter>=1.1.0,<2.0; python_version == "2.7"
|
||||
django-filter>=1.1.0; python_version >= "3.4"
|
||||
djangorestframework-camel-case>=0.2.0
|
||||
@@ -6,7 +6,18 @@ import os
|
||||
import sys
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
requirements_setup = ['setuptools_scm==1.15.6']
|
||||
|
||||
def read_req(req_file):
|
||||
with open(os.path.join('requirements', req_file)) as req:
|
||||
return [line for line in req.readlines() if line and not line.isspace()]
|
||||
|
||||
|
||||
with io.open('README.rst', encoding='utf-8') as readme:
|
||||
description = readme.read()
|
||||
|
||||
requirements = ['djangorestframework>=3.7.0'] + read_req('base.txt')
|
||||
requirements_setup = read_req('setup.txt')
|
||||
requirements_validation = read_req('validation.txt')
|
||||
|
||||
|
||||
def _install_setup_requires(attrs):
|
||||
@@ -40,18 +51,6 @@ if 'sdist' in sys.argv:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def read_req(req_file):
|
||||
with open(os.path.join('requirements', req_file)) as req:
|
||||
return [line for line in req.readlines() if line and not line.isspace()]
|
||||
|
||||
|
||||
with io.open('README.rst', encoding='utf-8') as readme:
|
||||
description = readme.read()
|
||||
|
||||
requirements = ['djangorestframework>=3.7.0'] + read_req('base.txt')
|
||||
requirements_validation = read_req('validation.txt')
|
||||
|
||||
setup(
|
||||
name='drf-yasg',
|
||||
use_scm_version=True,
|
||||
|
||||
@@ -4,7 +4,6 @@ import logging
|
||||
from django.utils.encoding import force_text
|
||||
from rest_framework import serializers
|
||||
from rest_framework.utils import encoders, json
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
|
||||
from .. import openapi
|
||||
from ..utils import is_list_view
|
||||
@@ -182,7 +181,7 @@ class FieldInspector(BaseInspector):
|
||||
|
||||
- arguments specified by the ``kwargs`` parameter of :meth:`._get_partial_types`
|
||||
- ``instance_kwargs`` passed to the constructor function
|
||||
- ``title``, ``description``, ``required``, ``default`` and ``read_only`` inferred from the field,
|
||||
- ``title``, ``description``, ``required`` and ``default`` inferred from the field,
|
||||
where appropriate
|
||||
|
||||
If ``existing_object`` is not ``None``, it is updated instead of creating a new object.
|
||||
@@ -233,11 +232,6 @@ class FieldInspector(BaseInspector):
|
||||
if default is not None:
|
||||
instance_kwargs['default'] = default
|
||||
|
||||
if 'read_only' not in instance_kwargs and swagger_object_type == openapi.Schema:
|
||||
# TODO: read_only is only relevant for schema `properties` - should not be generated in other cases
|
||||
if field.read_only:
|
||||
instance_kwargs['read_only'] = True
|
||||
|
||||
instance_kwargs.setdefault('title', title)
|
||||
instance_kwargs.setdefault('description', description)
|
||||
instance_kwargs.update(kwargs)
|
||||
@@ -327,9 +321,6 @@ class ViewInspector(BaseInspector):
|
||||
if self.method.lower() not in ["get", "delete"]:
|
||||
return False
|
||||
|
||||
if not isinstance(self.view, GenericViewSet):
|
||||
return True
|
||||
|
||||
return is_list_view(self.path, self.method, self.view)
|
||||
|
||||
def get_filter_parameters(self):
|
||||
@@ -351,10 +342,7 @@ class ViewInspector(BaseInspector):
|
||||
|
||||
:rtype: bool
|
||||
"""
|
||||
if not hasattr(self.view, 'paginator'):
|
||||
return False
|
||||
|
||||
if self.view.paginator is None:
|
||||
if not getattr(self.view, 'paginator', None):
|
||||
return False
|
||||
|
||||
if self.method.lower() != 'get':
|
||||
|
||||
@@ -63,11 +63,18 @@ class InlineSerializerInspector(SerializerInspector):
|
||||
def make_schema_definition():
|
||||
properties = OrderedDict()
|
||||
required = []
|
||||
for key, value in serializer.fields.items():
|
||||
key = self.get_property_name(key)
|
||||
properties[key] = self.probe_field_inspectors(value, ChildSwaggerType, use_references)
|
||||
if value.required:
|
||||
required.append(key)
|
||||
for property_name, child in serializer.fields.items():
|
||||
property_name = self.get_property_name(property_name)
|
||||
prop_kwargs = {
|
||||
'read_only': child.read_only or None
|
||||
}
|
||||
prop_kwargs = filter_none(prop_kwargs)
|
||||
|
||||
properties[property_name] = self.probe_field_inspectors(
|
||||
child, ChildSwaggerType, use_references, **prop_kwargs
|
||||
)
|
||||
if child.required:
|
||||
required.append(property_name)
|
||||
|
||||
return SwaggerType(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# Swagger UI Dist
|
||||
[](http://badge.fury.io/js/swagger-ui-dist)
|
||||
|
||||
# API
|
||||
|
||||
This module, `swagger-ui-dist`, exposes Swagger-UI's entire dist folder as a dependency-free npm module.
|
||||
Use `swagger-ui` instead, if you'd like to have npm install dependencies for you.
|
||||
|
||||
`SwaggerUIBundle` and `SwaggerUIStandalonePreset` can be imported:
|
||||
```javascript
|
||||
import { SwaggerUIBundle, SwaggerUIStandalonePreset } from "swagger-ui-dist"
|
||||
```
|
||||
|
||||
To get an absolute path to this directory for static file serving, use the exported `getAbsoluteFSPath` method:
|
||||
|
||||
```javascript
|
||||
const swaggerUiAssetPath = require("swagger-ui-dist").getAbsoluteFSPath()
|
||||
|
||||
// then instantiate server that serves files from the swaggerUiAssetPath
|
||||
```
|
||||
|
||||
For anything else, check the [Swagger-UI](https://github.com/swagger-api/swagger-ui) repository.
|
||||
@@ -1,95 +0,0 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
|
||||
<defs>
|
||||
<symbol viewBox="0 0 20 20" id="unlocked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="locked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="close">
|
||||
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow">
|
||||
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow-down">
|
||||
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
|
||||
</symbol>
|
||||
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="jump-to">
|
||||
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="expand">
|
||||
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
|
||||
</symbol>
|
||||
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "http://petstore.swagger.io/v2/swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+34
-28
@@ -4,6 +4,7 @@ from collections import OrderedDict
|
||||
|
||||
from rest_framework import serializers, status
|
||||
from rest_framework.mixins import DestroyModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||
from rest_framework.views import APIView
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -41,7 +42,7 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
|
||||
the `manual_parameters` argument.
|
||||
|
||||
If a ``Serializer`` class or instance is given, it will be automatically converted into a :class:`.Schema`
|
||||
used as a ``body`` :class:`.Parameter`, or into a list of ``form`` :class:`.Parameter`\ s, as appropriate.
|
||||
used as a ``body`` :class:`.Parameter`, or into a list of ``form`` :class:`.Parameter`\ s, as appropriate.
|
||||
|
||||
:param .Serializer query_serializer: if you use a ``Serializer`` to parse query parameters, you can pass it here
|
||||
and have :class:`.Parameter` objects be generated automatically from it.
|
||||
@@ -85,6 +86,7 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
|
||||
"""
|
||||
|
||||
def decorator(view_method):
|
||||
assert not any(hm in extra_overrides for hm in APIView.http_method_names), "HTTP method names not allowed here"
|
||||
data = {
|
||||
'auto_schema': auto_schema,
|
||||
'request_body': request_body,
|
||||
@@ -97,48 +99,52 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
|
||||
'paginator_inspectors': list(paginator_inspectors) if paginator_inspectors else None,
|
||||
'field_inspectors': list(field_inspectors) if field_inspectors else None,
|
||||
}
|
||||
data = {k: v for k, v in data.items() if v is not None}
|
||||
data = filter_none(data)
|
||||
data.update(extra_overrides)
|
||||
if not data: # pragma: no cover
|
||||
# no overrides to set, no use in doing more work
|
||||
return
|
||||
|
||||
# if the method is a detail_route or list_route, it will have a bind_to_methods attribute
|
||||
bind_to_methods = getattr(view_method, 'bind_to_methods', [])
|
||||
# if the method is actually a function based view (@api_view), it will have a 'cls' attribute
|
||||
view_cls = getattr(view_method, 'cls', None)
|
||||
http_method_names = getattr(view_cls, 'http_method_names', [])
|
||||
if bind_to_methods or http_method_names:
|
||||
|
||||
available_methods = http_method_names + bind_to_methods
|
||||
existing_data = getattr(view_method, '_swagger_auto_schema', {})
|
||||
|
||||
_methods = methods
|
||||
if methods or method:
|
||||
assert bool(methods) != bool(method), "specify either method or methods"
|
||||
assert not isinstance(methods, str), "`methods` expects to receive a list of methods;" \
|
||||
" use `method` for a single argument"
|
||||
if method:
|
||||
_methods = [method.lower()]
|
||||
else:
|
||||
_methods = [mth.lower() for mth in methods]
|
||||
assert all(mth in available_methods for mth in _methods), "http method not bound to view"
|
||||
assert not any(mth in existing_data for mth in _methods), "http method defined multiple times"
|
||||
|
||||
if available_methods:
|
||||
# detail_route, list_route or api_view
|
||||
assert bool(http_method_names) != bool(bind_to_methods), "this should never happen"
|
||||
available_methods = http_method_names + bind_to_methods
|
||||
existing_data = getattr(view_method, '_swagger_auto_schema', {})
|
||||
|
||||
if http_method_names:
|
||||
_route = "api_view"
|
||||
else:
|
||||
_route = "detail_route" if view_method.detail else "list_route"
|
||||
|
||||
_methods = methods
|
||||
if len(available_methods) > 1:
|
||||
assert methods or method, \
|
||||
"on multi-method %s, you must specify swagger_auto_schema on a per-method basis " \
|
||||
"using one of the `method` or `methods` arguments" % _route
|
||||
assert bool(methods) != bool(method), "specify either method or methods"
|
||||
assert not isinstance(methods, str), "`methods` expects to receive a list of methods;" \
|
||||
" use `method` for a single argument"
|
||||
if method:
|
||||
_methods = [method.lower()]
|
||||
else:
|
||||
_methods = [mth.lower() for mth in methods]
|
||||
assert not any(mth in existing_data for mth in _methods), "method defined multiple times"
|
||||
assert all(mth in available_methods for mth in _methods), "method not bound to %s" % _route
|
||||
|
||||
existing_data.update((mth.lower(), data) for mth in _methods)
|
||||
assert _methods, \
|
||||
"on multi-method api_view, detail_route or list_route, you must specify swagger_auto_schema on " \
|
||||
"a per-method basis using one of the `method` or `methods` arguments"
|
||||
else:
|
||||
existing_data[available_methods[0]] = data
|
||||
# for a single-method view we assume that single method as the decorator target
|
||||
_methods = _methods or available_methods
|
||||
|
||||
existing_data.update((mth.lower(), data) for mth in _methods)
|
||||
view_method._swagger_auto_schema = existing_data
|
||||
else:
|
||||
assert method is None and methods is None, \
|
||||
assert not _methods, \
|
||||
"the methods argument should only be specified when decorating a detail_route or list_route; you " \
|
||||
"should also ensure that you put the swagger_auto_schema decorator AFTER (above) the _route decorator"
|
||||
assert not existing_data, "a single view method should only be decorated once"
|
||||
view_method._swagger_auto_schema = data
|
||||
|
||||
return view_method
|
||||
@@ -166,7 +172,7 @@ def is_list_view(path, method, view):
|
||||
# a detail_route is surely not a list route
|
||||
return False
|
||||
|
||||
# for APIView, if it's a detail view it can't also be a list view
|
||||
# for GenericAPIView, if it's a detail view it can't also be a list view
|
||||
if isinstance(view, (RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin)):
|
||||
return False
|
||||
|
||||
|
||||
@@ -94,8 +94,7 @@ def get_schema_view(info=None, url=None, patterns=None, urlconf=None, public=Fal
|
||||
|
||||
Arguments described in :meth:`.as_cached_view`.
|
||||
"""
|
||||
if not cls.public:
|
||||
view = vary_on_headers('Cookie', 'Authorization')(view)
|
||||
view = vary_on_headers('Cookie', 'Authorization')(view)
|
||||
view = cache_page(cache_timeout, **cache_kwargs)(view)
|
||||
view = deferred_never_cache(view) # disable in-browser caching
|
||||
return view
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
from __future__ import print_function
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
User.objects.filter(username='admin').delete()
|
||||
User.objects.create_superuser('admin', 'admin@admin.admin', 'passwordadmin')
|
||||
username = 'admin'
|
||||
email = 'admin@admin.admin'
|
||||
password = 'passwordadmin'
|
||||
User.objects.filter(username=username).delete()
|
||||
User.objects.create_superuser(username, email, password)
|
||||
|
||||
print("Created superuser '%s <%s>' with password '%s'" % (username, email, password))
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
drf-yasg[validation]
|
||||
Django>=1.11.7
|
||||
-r ../requirements/testproj.txt
|
||||
@@ -1109,7 +1109,6 @@ definitions:
|
||||
type: string
|
||||
format: slug
|
||||
pattern: ^[-a-zA-Z0-9_]+$
|
||||
readOnly: true
|
||||
readOnly: true
|
||||
uniqueItems: true
|
||||
securityDefinitions:
|
||||
|
||||
@@ -52,10 +52,7 @@ def test_caching(client, validate_schema):
|
||||
prev_schema = None
|
||||
|
||||
for i in range(3):
|
||||
_validate_ui_schema_view(client, '/cached/redoc/', 'redoc/redoc.min.js')
|
||||
_validate_text_schema_view(client, validate_schema, '/cached/redoc/?format=openapi', json.loads)
|
||||
_validate_ui_schema_view(client, '/cached/swagger/', 'swagger-ui-dist/swagger-ui-bundle.js')
|
||||
_validate_text_schema_view(client, validate_schema, '/cached/swagger/?format=openapi', json.loads)
|
||||
_validate_text_schema_view(client, validate_schema, '/cached/swagger.yaml', yaml_sane_load)
|
||||
|
||||
json_schema = client.get('/cached/swagger.json')
|
||||
assert json_schema.status_code == 200
|
||||
|
||||
@@ -59,7 +59,7 @@ max-line-length = 120
|
||||
exclude = **/migrations/*
|
||||
|
||||
[isort]
|
||||
skip = .eggs,.tox,docs
|
||||
skip = .eggs,.tox,docs,env,venv
|
||||
skip_glob = **/migrations/*
|
||||
not_skip = __init__.py
|
||||
atomic = true
|
||||
|
||||
+5
-3
@@ -1,7 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
set -ev
|
||||
npm update
|
||||
cp node_modules/redoc/dist/redoc.min.js src/drf_yasg/static/drf-yasg/redoc/redoc.min.js
|
||||
cp -r node_modules/swagger-ui-dist src/drf_yasg/static/drf-yasg/
|
||||
rm -f src/drf_yasg/static/drf-yasg/swagger-ui-dist/package.json src/drf_yasg/static/drf-yasg/swagger-ui-dist/.npmignore
|
||||
pushd src/drf_yasg/static/drf-yasg/swagger-ui-dist/ >/dev/null
|
||||
rm -f package.json .npmignore README.md
|
||||
rm -f index.html *.map
|
||||
popd >/dev/null
|
||||
|
||||
Reference in New Issue
Block a user