Skip to content

Commit

Permalink
Add documentation about excluding endpoints
Browse files Browse the repository at this point in the history
Closes #50.
  • Loading branch information
axnsan12 committed Jan 24, 2018
1 parent a3e81ef commit a211184
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 18 deletions.
27 changes: 25 additions & 2 deletions docs/custom_spec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
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:

**************************************
Expand Down Expand Up @@ -200,8 +225,6 @@ This custom generator can be put to use by setting it as the :attr:`.generator_c
``Inspector`` classes
---------------------

.. versionadded:: 1.1

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.PaginatorInspector` classes and use them with
Expand Down
22 changes: 19 additions & 3 deletions docs/openapi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
Functional overview
**********************


------------------------------
OpenAPI specification overview
------------------------------
Expand Down Expand Up @@ -155,9 +154,26 @@ This section describes where information is sourced from when using the default

Other versioning schemes are not presently supported.

---------------------
A note on limitations
---------------------

When schema generation is requested, available endpoints are inspected by enumeration all the routes registered in
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:

.. versionadded:: 1.2
Base path and versioning support.
* 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
.. _FORCE_SCRIPT_NAME: https://docs.djangoproject.com/en/2.0/ref/settings/#force-script-name
2 changes: 0 additions & 2 deletions docs/rendering.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ You can use your custom renderer classes as kwargs to :meth:`.SchemaView.as_cach
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
to get it without having to start the web server:

Expand Down
3 changes: 3 additions & 0 deletions src/drf_yasg/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ def should_include_endpoint(self, path, callback, app_name='', namespace='', url
if version and version not in namespace.split(':'):
return False

if getattr(callback.cls, 'swagger_schema', object()) is None:
return False

return True

def replace_version(self, path, callback):
Expand Down
4 changes: 2 additions & 2 deletions src/drf_yasg/inspectors/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ def get_request_serializer(self):
if body_override is no_body:
return None
if self.method not in self.body_methods:
raise SwaggerGenerationError("request_body can only be applied to PUT, PATCH or POST views; "
"are you looking for query_serializer or manual_parameters?")
raise SwaggerGenerationError("request_body can only be applied to (" + ','.join(self.body_methods) +
"); are you looking for query_serializer or manual_parameters?")
if isinstance(body_override, openapi.Schema.OR_REF):
return body_override
return force_serializer_instance(body_override)
Expand Down
15 changes: 6 additions & 9 deletions src/drf_yasg/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
#: used to forcibly remove the body of a request via :func:`.swagger_auto_schema`
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,
responses=None, field_inspectors=None, filter_inspectors=None, paginator_inspectors=None,
**extra_overrides):
Expand All @@ -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.
.. 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 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;
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
will be used as the ``schema`` property of a :class:`.Parameter` with ``in: 'body'``.
Expand Down Expand Up @@ -92,7 +88,6 @@ 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,
'query_serializer': query_serializer,
'manual_parameters': manual_parameters,
Expand All @@ -105,6 +100,8 @@ def decorator(view_method):
'field_inspectors': list(field_inspectors) if field_inspectors else None,
}
data = filter_none(data)
if auto_schema is not unset:
data['auto_schema'] = auto_schema
data.update(extra_overrides)
if not data: # pragma: no cover
# no overrides to set, no use in doing more work
Expand Down

0 comments on commit a211184

Please sign in to comment.