1.. |br| raw:: html 2 3 <br /> 4 5********************** 6Functional overview 7********************** 8 9------------------------------ 10OpenAPI specification overview 11------------------------------ 12 13This library generates OpenAPI 2.0 documents. The authoritative specification for this document's structure will always 14be the official documentation over at `swagger.io <https://swagger.io/>`__ and the `OpenAPI 2.0 specification 15page <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md>`__. 16 17Because the above specifications are a bit heavy and convoluted, here is a general overview of how the specification 18is structured, starting from the root ``Swagger`` object. 19 20* :class:`.Swagger` object 21 + ``info``, ``schemes``, ``securityDefinitions`` and other informative attributes 22 + ``paths``: :class:`.Paths` object 23 A list of all the paths in the API in the form of a mapping 24 25 - ``{path}``: :class:`.PathItem` - each :class:`.PathItem` has multiple operations keyed by method 26 * ``{http_method}``: :class:`.Operation` 27 Each operation is thus uniquely identified by its ``(path, http_method)`` combination, 28 e.g. ``GET /articles/``, ``POST /articles/``, etc. 29 * ``parameters``: [:class:`.Parameter`] - and a list of path parameters 30 + ``definitions``: named Models 31 A list of all the named models in the API in the form of a mapping 32 33 - ``{ModelName}``: :class:`.Schema` 34 35* :class:`.Operation` contains the following information about each operation: 36 + ``parameters``: [:class:`.Parameter`] 37 A list of all the *query*, *header* and *form* parameters accepted by the operation. 38 39 - there can also be **at most one** body parameter whose structure is represented by a 40 :class:`.Schema` or a reference to one (:class:`.SchemaRef`) 41 + ``responses``: :class:`.Responses` 42 A list of all the possible responses the operation is expected to return. Each response can optionally have a 43 :class:`.Schema` which describes the structure of its body. 44 45 - ``{status_code}``: :class:`.Response` - mapping of status code to response definition 46 47 + ``operationId`` - should be unique across all operations 48 + ``tags`` - used to group operations in the listing 49 50It is interesting to note the main differences between :class:`.Parameter` and :class:`.Schema` objects: 51 52+----------------------------------------------------------+-----------------------------------------------------------+ 53| :class:`.Schema` | :class:`.Parameter` | 54+==========================================================+===========================================================+ 55| Can nest other Schemas | Cannot nest other Parameters |br| | 56| | Can only nest a Schema if the parameter is ``in: body`` | 57+----------------------------------------------------------+-----------------------------------------------------------+ 58| Cannot describe file uploads |br| | Can describe file uploads via ``type`` = ``file``, |br| | 59| - ``file`` is not permitted as a value for ``type`` | but only as part of a form :class:`.Operation` [#formop]_ | 60+----------------------------------------------------------+-----------------------------------------------------------+ 61| Can be used in :class:`.Response`\ s | Cannot be used in :class:`.Response`\ s | 62+----------------------------------------------------------+-----------------------------------------------------------+ 63| Cannot be used in form :class:`.Operation`\ s [#formop]_ | Can be used in form :class:`.Operation`\ s [#formop]_ | 64+----------------------------------------------------------+-----------------------------------------------------------+ 65| Can only describe request or response bodies | Can describe ``query``, ``form``, ``header`` or ``path`` | 66| | parameters | 67+----------------------------------------------------------+-----------------------------------------------------------+ 68 69.. [#formop] a form Operation is an :class:`.Operation` that consumes ``multipart/form-data`` or 70 ``application/x-www-form-urlencoded`` content 71 72 * a form Operation cannot have ``body`` parameters 73 * a non-form operation cannot have ``form`` parameters 74 75---------------- 76Default behavior 77---------------- 78 79This section describes where information is sourced from when using the default generation process. 80 81* :class:`.Paths` are generated by exploring the patterns registered in your default ``urlconf``, or the ``patterns`` 82 and ``urlconf`` you specified when constructing :class:`.OpenAPISchemaGenerator`; only views inheriting from Django 83 Rest Framework's ``APIView`` are looked at, all other views are ignored 84* ``path`` :class:`.Parameter`\ s are generated by looking in the URL pattern for any template parameters; attempts are 85 made to guess their type from the views ``queryset`` and ``lookup_field``, if applicable. You can override path 86 parameters via ``manual_parameters`` in :ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>`. 87* ``query`` :class:`.Parameter`\ s - i.e. parameters specified in the URL as ``/path/?query1=value&query2=value`` - 88 are generated from your view's ``filter_backends`` and ``paginator``, if any are declared. Additional parameters can 89 be specified via the ``query_serializer`` and ``manual_parameters`` arguments of 90 :ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>` 91* The request body is only generated for the HTTP ``POST``, ``PUT`` and ``PATCH`` methods, and is sourced from the 92 view's ``serializer_class``. You can also override the request body using the ``request_body`` argument of 93 :ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>`. 94 95 - if the view represents a form request (that is, all its parsers are of the ``multipart/form-data`` or 96 ``application/x-www-form-urlencoded`` media types), the request body will be output as ``form`` 97 :class:`.Parameter`\ s 98 - if it is not a form request, the request body will be output as a single ``body`` :class:`.Parameter` wrapped 99 around a :class:`.Schema` 100 101* ``header`` :class:`.Parameter`\ s are supported by the OpenAPI specification but are never generated by this library; 102 you can still add them using ``manual_parameters``. 103* :class:`.Responses` are generated as follows: 104 105 + if ``responses`` is provided to :ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>` and contains at least 106 one success status code (i.e. any `2xx` status code), no automatic response is generated and the given response 107 is used as described in the :func:`@swagger_auto_schema documentation <.swagger_auto_schema>` 108 + otherwise, an attempt is made to generate a default response: 109 110 - the success status code is assumed to be ``204`` for ``DELETE`` requests, ``201`` for ``POST`` requests, and 111 ``200`` for all other request methods 112 - if the view has a request body, the same ``Serializer`` or :class:`.Schema` as in the request body is used 113 in generating the :class:`.Response` schema; this is inline with the default ``GenericAPIView`` and 114 ``GenericViewSet`` behavior 115 - if the view has no request body, its ``serializer_class`` is used to generate the :class:`.Response` schema 116 - if the view is a list view (as defined by :func:`.is_list_view`), the response schema is wrapped in an array 117 - if the view is also paginated, the response schema is then wrapped in the appropriate paging response structure 118 - the description of the response is left blank 119 120* :class:`.Response` headers are supported by the OpenAPI specification but not currently supported by this library; 121 you can still add them manually by providing an `appropriately structured dictionary 122 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#headersObject>`_ 123 to the ``headers`` property of a :class:`.Response` object 124* *descriptions* for :class:`.Operation`\ s, :class:`.Parameter`\ s and :class:`.Schema`\ s are picked up from 125 docstrings and ``help_text`` attributes in the same manner as the `default DRF SchemaGenerator 126 <http://www.django-rest-framework.org/api-guide/schemas/#schemas-as-documentation>`_ 127* .. _custom-spec-base-url: 128 129 The base URL for the API consists of three values - the ``host``, ``schemes`` and ``basePath`` attributes 130* The host name and scheme are determined, in descending order of priority: 131 132 + from the ``url`` argument passed to :func:`.get_schema_view` (more specifically, to the underlying 133 :class:`.OpenAPISchemaGenerator`) 134 + from the :ref:`DEFAULT_API_URL setting <default-swagger-settings>` 135 + inferred from the request made to the schema endpoint 136 137 For example, an url of ``https://www.example.com:8080/some/path`` will populate the ``host`` and ``schemes`` 138 attributes with ``www.example.com:8080`` and ``['https']``, respectively. The path component will be ignored. 139* The base path is determined as the concatenation of two variables: 140 141 #. the `SCRIPT_NAME`_ wsgi environment variable; this is set, for example, when serving the site from a 142 sub-path using web server url rewriting 143 144 .. Tip:: 145 146 The Django `FORCE_SCRIPT_NAME`_ setting can be used to override the `SCRIPT_NAME`_ or set it when it's 147 missing from the environment. 148 149 #. the longest common path prefix of all the urls in your API - see :meth:`.determine_path_prefix` 150 151* When using API versioning with ``NamespaceVersioning`` or ``URLPathVersioning``, versioned endpoints that do not 152 match the version used to access the ``SchemaView`` will be excluded from the endpoint list - for example, 153 ``/api/v1.0/endpoint`` will be shown when viewing ``/api/v1.0/swagger/``, while ``/api/v2.0/endpoint`` will not 154 155 Other versioning schemes are not presently supported. 156 157--------------------- 158A note on limitations 159--------------------- 160 161When schema generation is requested, available endpoints are inspected by enumeration all the routes registered in 162Django's urlconf. Each registered view is then artificially instantiated for introspection, and it is this step that 163brings some limitations to what can be done: 164 165* the ``request`` the view sees will always be the request made against the schema view endpoint 166 - e.g. ``GET /swagger.yaml`` 167* path parameters will not be filled 168 169This means that you could get surprizing results if your ``get_serializer`` or ``get_serializer_class`` methods 170depend on the incoming request, call ``get_object`` or in general depend on any stateful logic. You can prevent this 171in a few ways: 172 173* provide a fixed serializer for request and response body introspection using 174 :ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>`, to prevent ``get_serializer`` from being called on 175 the view 176* :ref:`exclude your endpoint from introspection <custom-spec-excluding-endpoints>` 177* use the ``swagger_fake_view`` marker to detect requests generated by ``drf-yasg``: 178 179 .. code-block:: python 180 181 def get_serializer_class(self): 182 if getattr(self, 'swagger_fake_view', False): 183 return TodoTreeSerializer 184 185 raise NotImplementedError("must not call this") 186 187.. _SCRIPT_NAME: https://www.python.org/dev/peps/pep-0333/#environ-variables 188.. _FORCE_SCRIPT_NAME: https://docs.djangoproject.com/en/2.0/ref/settings/#force-script-name 189