1.. role:: python(code)
2 :language: python
3
4########################################
5drf-yasg - Yet another Swagger generator
6########################################
7
8|travis| |nbsp| |codecov| |nbsp| |rtd-badge| |nbsp| |pypi-version|
9
10Generate **real** Swagger/OpenAPI 2.0 specifications from a Django Rest Framework API.
11
12Compatible with
13
14- **Django Rest Framework**: 3.10, 3.11, 3.12
15- **Django**: 2.2, 3.0, 3.1
16- **Python**: 3.6, 3.7, 3.8, 3.9
17
18Only the latest patch version of each ``major.minor`` series of Python, Django and Django REST Framework is supported.
19
20**Only the latest version of drf-yasg is supported.** Support of old versions is dropped immediately with the release
21of a new version. Please do not create issues before upgrading to the latest release available at the time. Regression
22reports are accepted and will be resolved with a new release as quickly as possible. Removed features will usually go
23through a deprecation cycle of a few minor releases.
24
25Resources:
26
27* **Source**: https://github.com/axnsan12/drf-yasg/
28* **Documentation**: https://drf-yasg.readthedocs.io/
29* **Changelog**: https://drf-yasg.readthedocs.io/en/stable/changelog.html
30* **Live demo**: https://drf-yasg-demo.herokuapp.com/
31
32|heroku-button|
33
34
35****************
36OpenAPI 3.0 note
37****************
38
39If you are looking to add Swagger/OpenAPI support to a new project you might want to take a look at
40`drf-spectacular <https://github.com/tfranzel/drf-spectacular>`_, which is an actively maintained new library that
41shares most of the goals of this project, while working with OpenAPI 3.0 schemas.
42
43OpenAPI 3.0 provides a lot more flexibility than 2.0 in the types of API that can be described.
44``drf-yasg`` is unlikely to soon, if ever, get support for OpenAPI 3.0.
45
46
47********
48Features
49********
50
51- full support for nested Serializers and Schemas
52- response schemas and descriptions
53- model definitions compatible with codegen tools
54- customization hooks at all points in the spec generation process
55- JSON and YAML format for spec
56- bundles latest version of
57 `swagger-ui <https://github.com/swagger-api/swagger-ui>`_ and
58 `redoc <https://github.com/Rebilly/ReDoc>`_ for viewing the generated documentation
59- schema view is cacheable out of the box
60- generated Swagger schema can be automatically validated by
61 `swagger-spec-validator <https://github.com/Yelp/swagger_spec_validator>`_
62- supports Django REST Framework API versioning with ``URLPathVersioning`` and ``NamespaceVersioning``; other DRF
63 or custom versioning schemes are not currently supported
64
65.. figure:: https://raw.githubusercontent.com/axnsan12/drf-yasg/1.0.2/screenshots/redoc-nested-response.png
66 :width: 100%
67 :figwidth: image
68 :alt: redoc screenshot
69
70 **Fully nested request and response schemas.**
71
72.. figure:: https://raw.githubusercontent.com/axnsan12/drf-yasg/1.0.2/screenshots/swagger-ui-list.png
73 :width: 100%
74 :figwidth: image
75 :alt: swagger-ui screenshot
76
77 **Choose between redoc and swagger-ui.**
78
79.. figure:: https://raw.githubusercontent.com/axnsan12/drf-yasg/1.0.2/screenshots/swagger-ui-models.png
80 :width: 100%
81 :figwidth: image
82 :alt: model definitions screenshot
83
84 **Real Model definitions.**
85
86
87*****************
88Table of contents
89*****************
90
91.. contents::
92 :depth: 4
93
94*****
95Usage
96*****
97
980. Installation
99===============
100
101The preferred instalation method is directly from pypi:
102
103.. code:: console
104
105 pip install -U drf-yasg
106
107Additionally, if you want to use the built-in validation mechanisms (see `4. Validation`_), you need to install
108some extra requirements:
109
110.. code:: console
111
112 pip install -U drf-yasg[validation]
113
114.. _readme-quickstart:
115
1161. Quickstart
117=============
118
119In ``settings.py``:
120
121.. code:: python
122
123 INSTALLED_APPS = [
124 ...
125 'django.contrib.staticfiles', # required for serving swagger ui's css/js files
126 'drf_yasg',
127 ...
128 ]
129
130In ``urls.py``:
131
132.. code:: python
133
134 ...
135 from rest_framework import permissions
136 from drf_yasg.views import get_schema_view
137 from drf_yasg import openapi
138
139 ...
140
141 schema_view = get_schema_view(
142 openapi.Info(
143 title="Snippets API",
144 default_version='v1',
145 description="Test description",
146 terms_of_service="https://www.google.com/policies/terms/",
147 contact=openapi.Contact(email="contact@snippets.local"),
148 license=openapi.License(name="BSD License"),
149 ),
150 public=True,
151 permission_classes=(permissions.AllowAny,),
152 )
153
154 urlpatterns = [
155 url(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
156 url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
157 url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
158 ...
159 ]
160
161This exposes 4 endpoints:
162
163* A JSON view of your API specification at ``/swagger.json``
164* A YAML view of your API specification at ``/swagger.yaml``
165* A swagger-ui view of your API specification at ``/swagger/``
166* A ReDoc view of your API specification at ``/redoc/``
167
1682. Configuration
169================
170
171---------------------------------
172a. ``get_schema_view`` parameters
173---------------------------------
174
175- ``info`` - Swagger API Info object; if omitted, defaults to ``DEFAULT_INFO``
176- ``url`` - API base url; if left blank will be deduced from the location the view is served at
177- ``patterns`` - passed to SchemaGenerator
178- ``urlconf`` - passed to SchemaGenerator
179- ``public`` - if False, includes only endpoints the current user has access to
180- ``validators`` - a list of validator names to apply on the generated schema; only ``ssv`` is currently supported
181- ``generator_class`` - schema generator class to use; should be a subclass of ``OpenAPISchemaGenerator``
182- ``authentication_classes`` - authentication classes for the schema view itself
183- ``permission_classes`` - permission classes for the schema view itself
184
185-------------------------------
186b. ``SchemaView`` options
187-------------------------------
188
189- :python:`SchemaView.with_ui(renderer, cache_timeout, cache_kwargs)` - get a view instance using the
190 specified UI renderer; one of ``swagger``, ``redoc``
191- :python:`SchemaView.without_ui(cache_timeout, cache_kwargs)` - get a view instance with no UI renderer;
192 same as ``as_cached_view`` with no kwargs
193- :python:`SchemaView.as_cached_view(cache_timeout, cache_kwargs, **initkwargs)` - same as ``as_view``,
194 but with optional caching
195- you can, of course, call :python:`as_view` as usual
196
197All of the first 3 methods take two optional arguments, ``cache_timeout`` and ``cache_kwargs``; if present,
198these are passed on to Django’s :python:`cached_page` decorator in order to enable caching on the resulting view.
199See `3. Caching`_.
200
201----------------------------------------------
202c. ``SWAGGER_SETTINGS`` and ``REDOC_SETTINGS``
203----------------------------------------------
204
205Additionally, you can include some more settings in your ``settings.py`` file.
206See https://drf-yasg.readthedocs.io/en/stable/settings.html for details.
207
208
2093. Caching
210==========
211
212Since the schema does not usually change during the lifetime of the django process, there is out of the box support for
213caching the schema view in-memory, with some sane defaults:
214
215* caching is enabled by the `cache_page <https://docs.djangoproject.com/en/1.11/topics/cache/#the-per-view-cache>`__
216 decorator, using the default Django cache backend, can be changed using the ``cache_kwargs`` argument
217* HTTP caching of the response is blocked to avoid confusing situations caused by being shown stale schemas
218* the cached schema varies on the ``Cookie`` and ``Authorization`` HTTP headers to enable filtering of visible endpoints
219 according to the authentication credentials of each user; note that this means that every user accessing the schema
220 will have a separate schema cached in memory.
221
2224. Validation
223=============
224
225Given the numerous methods to manually customize the generated schema, it makes sense to validate the result to ensure
226it still conforms to OpenAPI 2.0. To this end, validation is provided at the generation point using python swagger
227libraries, and can be activated by passing :python:`validators=['ssv']` to ``get_schema_view``; if the generated
228schema is not valid, a :python:`SwaggerValidationError` is raised by the handling codec.
229
230**Warning:** This internal validation can slow down your server.
231Caching can mitigate the speed impact of validation.
232
233The provided validation will catch syntactic errors, but more subtle violations of the spec might slip by them. To
234ensure compatibility with code generation tools, it is recommended to also employ one or more of the following methods:
235
236-------------------------------
237``swagger-ui`` validation badge
238-------------------------------
239
240Online
241^^^^^^
242
243If your schema is publicly accessible, `swagger-ui` will automatically validate it against the official swagger
244online validator and display the result in the bottom-right validation badge.
245
246Offline
247^^^^^^^
248
249If your schema is not accessible from the internet, you can run a local copy of
250`swagger-validator <https://hub.docker.com/r/swaggerapi/swagger-validator/>`_ and set the ``VALIDATOR_URL`` accordingly:
251
252.. code:: python
253
254 SWAGGER_SETTINGS = {
255 ...
256 'VALIDATOR_URL': 'http://localhost:8189',
257 ...
258 }
259
260.. code:: console
261
262 $ docker run --name swagger-validator -d -p 8189:8080 --add-host test.local:10.0.75.1 swaggerapi/swagger-validator
263 84dabd52ba967c32ae6b660934fa6a429ca6bc9e594d56e822a858b57039c8a2
264 $ curl http://localhost:8189/debug?url=http://test.local:8002/swagger/?format=openapi
265 {}
266
267---------------------
268Using ``swagger-cli``
269---------------------
270
271https://www.npmjs.com/package/swagger-cli
272
273.. code:: console
274
275 $ npm install -g swagger-cli
276 [...]
277 $ swagger-cli validate http://test.local:8002/swagger.yaml
278 http://test.local:8002/swagger.yaml is valid
279
280--------------------------------------------------------------
281Manually on `editor.swagger.io <https://editor.swagger.io/>`__
282--------------------------------------------------------------
283
284Importing the generated spec into https://editor.swagger.io/ will automatically trigger validation on it.
285This method is currently the only way to get both syntactic and semantic validation on your specification.
286The other validators only provide JSON schema-level validation, but miss things like duplicate operation names,
287improper content types, etc
288
2895. Code generation
290==================
291
292You can use the specification outputted by this library together with
293`swagger-codegen <https://github.com/swagger-api/swagger-codegen>`_ to generate client code in your language of choice:
294
295.. code:: console
296
297 $ docker run --rm -v ${PWD}:/local swaggerapi/swagger-codegen-cli generate -i /local/tests/reference.yaml -l javascript -o /local/.codegen/js
298
299See the github page linked above for more details.
300
301.. _readme-testproj:
302
3036. Example project
304==================
305
306For additional usage examples, you can take a look at the test project in the ``testproj`` directory:
307
308.. code:: console
309
310 $ git clone https://github.com/axnsan12/drf-yasg.git
311 $ cd drf-yasg
312 $ virtualenv venv
313 $ source venv/bin/activate
314 (venv) $ cd testproj
315 (venv) $ python -m pip install -U pip setuptools
316 (venv) $ pip install -U -r requirements.txt
317 (venv) $ python manage.py migrate
318 (venv) $ python manage.py runserver
319 (venv) $ firefox localhost:8000/swagger/
320
321************************
322Third-party integrations
323************************
324
325djangorestframework-camel-case
326===============================
327
328Integration with `djangorestframework-camel-case <https://github.com/vbabiy/djangorestframework-camel-case>`_ is
329provided out of the box - if you have ``djangorestframework-camel-case`` installed and your ``APIView`` uses
330``CamelCaseJSONParser`` or ``CamelCaseJSONRenderer``, all property names will be converted to *camelCase* by default.
331
332djangorestframework-recursive
333===============================
334
335Integration with `djangorestframework-recursive <https://github.com/heywbj/django-rest-framework-recursive>`_ is
336provided out of the box - if you have ``djangorestframework-recursive`` installed.
337
338.. |travis| image:: https://img.shields.io/travis/axnsan12/drf-yasg/master.svg
339 :target: https://travis-ci.org/axnsan12/drf-yasg
340 :alt: Travis CI
341
342.. |codecov| image:: https://img.shields.io/codecov/c/github/axnsan12/drf-yasg/master.svg
343 :target: https://codecov.io/gh/axnsan12/drf-yasg
344 :alt: Codecov
345
346.. |pypi-version| image:: https://img.shields.io/pypi/v/drf-yasg.svg
347 :target: https://pypi.org/project/drf-yasg/
348 :alt: PyPI
349
350.. |rtd-badge| image:: https://img.shields.io/readthedocs/drf-yasg.svg
351 :target: https://drf-yasg.readthedocs.io/
352 :alt: ReadTheDocs
353
354.. |heroku-button| image:: https://www.herokucdn.com/deploy/button.svg
355 :target: https://heroku.com/deploy?template=https://github.com/axnsan12/drf-yasg
356 :alt: Heroku deploy button
357
358.. |nbsp| unicode:: 0xA0
359 :trim:
360