Add documentation about excluding endpoints

Closes #50.
openapi3
Cristi Vîjdea 2018-01-24 17:38:10 +02:00
parent a3e81ef7f6
commit a211184478
6 changed files with 55 additions and 18 deletions

View File

@ -9,6 +9,31 @@ Custom schema generation
If the default spec generation does not quite match what you were hoping to achieve, ``drf-yasg`` provides some If the default spec generation does not quite match what you were hoping to achieve, ``drf-yasg`` provides some
custom behavior hooks by default. custom behavior hooks by default.
.. _custom-spec-excluding-endpoints:
*******************
Excluding endpoints
*******************
You can prevent a view from being included in the Swagger view by setting its class-level ``swagger_schema``
attribute to ``None``, or you can prevent an operation from being included by setting its ``auto_schema`` override
to none in :ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>`:
.. code-block:: python
class UserList(APIView):
swagger_schema = None
# all methods of the UserList class will be excluded
...
# only the GET method will be shown in Swagger
@swagger_auto_schema(method='put', auto_schema=None)
@swagger_auto_schema(methods=['get'], ...)
@api_view(['GET', 'PUT'])
def user_detail(request, pk):
pass
.. _custom-spec-swagger-auto-schema: .. _custom-spec-swagger-auto-schema:
************************************** **************************************
@ -200,8 +225,6 @@ This custom generator can be put to use by setting it as the :attr:`.generator_c
``Inspector`` classes ``Inspector`` classes
--------------------- ---------------------
.. versionadded:: 1.1
For customizing behavior related to specific field, serializer, filter or paginator classes you can implement the For customizing behavior related to specific field, serializer, filter or paginator classes you can implement the
:class:`~.inspectors.FieldInspector`, :class:`~.inspectors.SerializerInspector`, :class:`~.inspectors.FilterInspector`, :class:`~.inspectors.FieldInspector`, :class:`~.inspectors.SerializerInspector`, :class:`~.inspectors.FilterInspector`,
:class:`~.inspectors.PaginatorInspector` classes and use them with :class:`~.inspectors.PaginatorInspector` classes and use them with

View File

@ -6,7 +6,6 @@
Functional overview Functional overview
********************** **********************
------------------------------ ------------------------------
OpenAPI specification overview OpenAPI specification overview
------------------------------ ------------------------------
@ -155,9 +154,26 @@ This section describes where information is sourced from when using the default
Other versioning schemes are not presently supported. Other versioning schemes are not presently supported.
---------------------
A note on limitations
---------------------
.. versionadded:: 1.2 When schema generation is requested, available endpoints are inspected by enumeration all the routes registered in
Base path and versioning support. Django's urlconf. Each registered view is then artificially instantiated for introspection, and it is this step that
brings some limitations to what can be done:
* the ``request`` the view sees will always be the request made against the schema view endpoint
- e.g. ``GET /swagger.yaml``
* path parameters will not be filled
This means that you could get surprizing results if your ``get_serializer`` or ``get_serializer_class`` methods
depend on the incoming request, call ``get_object`` or in general depend on any stateful logic. You can prevent this
in a few ways:
* provide a fixed serializer for request and response body introspection using
:ref:`@swagger_auto_schema <custom-spec-swagger-auto-schema>`, to prevent ``get_serializer`` from being called on
the view
* :ref:`exclude your endpoint from introspection <custom-spec-excluding-endpoints>`
.. _SCRIPT_NAME: https://www.python.org/dev/peps/pep-0333/#environ-variables .. _SCRIPT_NAME: https://www.python.org/dev/peps/pep-0333/#environ-variables
.. _FORCE_SCRIPT_NAME: https://docs.djangoproject.com/en/2.0/ref/settings/#force-script-name .. _FORCE_SCRIPT_NAME: https://docs.djangoproject.com/en/2.0/ref/settings/#force-script-name

View File

@ -41,8 +41,6 @@ You can use your custom renderer classes as kwargs to :meth:`.SchemaView.as_cach
Management command Management command
****************** ******************
.. versionadded:: 1.1.1
If you only need a swagger spec file in YAML or JSON format, you can use the ``generate_swagger`` management command If you only need a swagger spec file in YAML or JSON format, you can use the ``generate_swagger`` management command
to get it without having to start the web server: to get it without having to start the web server:

View File

@ -45,6 +45,9 @@ class EndpointEnumerator(_EndpointEnumerator):
if version and version not in namespace.split(':'): if version and version not in namespace.split(':'):
return False return False
if getattr(callback.cls, 'swagger_schema', object()) is None:
return False
return True return True
def replace_version(self, path, callback): def replace_version(self, path, callback):

View File

@ -96,8 +96,8 @@ class SwaggerAutoSchema(ViewInspector):
if body_override is no_body: if body_override is no_body:
return None return None
if self.method not in self.body_methods: if self.method not in self.body_methods:
raise SwaggerGenerationError("request_body can only be applied to PUT, PATCH or POST views; " raise SwaggerGenerationError("request_body can only be applied to (" + ','.join(self.body_methods) +
"are you looking for query_serializer or manual_parameters?") "); are you looking for query_serializer or manual_parameters?")
if isinstance(body_override, openapi.Schema.OR_REF): if isinstance(body_override, openapi.Schema.OR_REF):
return body_override return body_override
return force_serializer_instance(body_override) return force_serializer_instance(body_override)

View File

@ -12,8 +12,10 @@ logger = logging.getLogger(__name__)
#: used to forcibly remove the body of a request via :func:`.swagger_auto_schema` #: used to forcibly remove the body of a request via :func:`.swagger_auto_schema`
no_body = object() no_body = object()
unset = object()
def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_body=None, query_serializer=None,
def swagger_auto_schema(method=None, methods=None, auto_schema=unset, request_body=None, query_serializer=None,
manual_parameters=None, operation_id=None, operation_description=None, security=None, manual_parameters=None, operation_id=None, operation_description=None, security=None,
responses=None, field_inspectors=None, filter_inspectors=None, paginator_inspectors=None, responses=None, field_inspectors=None, filter_inspectors=None, paginator_inspectors=None,
**extra_overrides): **extra_overrides):
@ -24,17 +26,11 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
The `auto_schema` and `operation_description` arguments take precendence over view- or method-level values. The `auto_schema` and `operation_description` arguments take precendence over view- or method-level values.
.. versionchanged:: 1.1
Added the ``extra_overrides`` and ``operatiod_id`` parameters.
.. versionchanged:: 1.1
Added the ``field_inspectors``, ``filter_inspectors`` and ``paginator_inspectors`` parameters.
:param str method: for multi-method views, the http method the options should apply to :param str method: for multi-method views, the http method the options should apply to
:param list[str] methods: for multi-method views, the http methods the options should apply to :param list[str] methods: for multi-method views, the http methods the options should apply to
:param .inspectors.SwaggerAutoSchema auto_schema: custom class to use for generating the Operation object; :param .inspectors.SwaggerAutoSchema auto_schema: custom class to use for generating the Operation object;
this overrides both the class-level ``swagger_schema`` attribute and the ``DEFAULT_AUTO_SCHEMA_CLASS`` this overrides both the class-level ``swagger_schema`` attribute and the ``DEFAULT_AUTO_SCHEMA_CLASS``
setting setting, and can be set to ``None`` to prevent this operation from being generated
:param .Schema,.SchemaRef,.Serializer request_body: custom request body, or :data:`.no_body`. The value given here :param .Schema,.SchemaRef,.Serializer request_body: custom request body, or :data:`.no_body`. The value given here
will be used as the ``schema`` property of a :class:`.Parameter` with ``in: 'body'``. will be used as the ``schema`` property of a :class:`.Parameter` with ``in: 'body'``.
@ -92,7 +88,6 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
def decorator(view_method): def decorator(view_method):
assert not any(hm in extra_overrides for hm in APIView.http_method_names), "HTTP method names not allowed here" assert not any(hm in extra_overrides for hm in APIView.http_method_names), "HTTP method names not allowed here"
data = { data = {
'auto_schema': auto_schema,
'request_body': request_body, 'request_body': request_body,
'query_serializer': query_serializer, 'query_serializer': query_serializer,
'manual_parameters': manual_parameters, 'manual_parameters': manual_parameters,
@ -105,6 +100,8 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
'field_inspectors': list(field_inspectors) if field_inspectors else None, 'field_inspectors': list(field_inspectors) if field_inspectors else None,
} }
data = filter_none(data) data = filter_none(data)
if auto_schema is not unset:
data['auto_schema'] = auto_schema
data.update(extra_overrides) data.update(extra_overrides)
if not data: # pragma: no cover if not data: # pragma: no cover
# no overrides to set, no use in doing more work # no overrides to set, no use in doing more work