diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c0f15faf..de3081a8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -32,7 +32,6 @@ Breaking changes / important additions: - added callback functionality (EXPERIMENTAL and subject to change due to pending issue) - Many thanks to all the contributors! - 0.21.2 (2022-02-01) ------------------- @@ -45,7 +44,6 @@ Breaking changes / important additions: - Some minor bugfixes and feature additions. Schemas using AcceptHeaderVersioning contain a small change. - 0.21.1 (2021-12-20) ------------------- @@ -64,7 +62,6 @@ Breaking changes / important additions: - Some minor bugfixes and small feature additions. No large schema changes are expected - 0.21.0 (2021-11-10) ------------------- @@ -95,7 +92,6 @@ Breaking changes / important additions: - Several other small fixes and additional settings for corner cases. This is mainly a y-steam release due to the potential impact on the Swagger UI and ``minLength`` changes. - 0.20.2 (2021-10-15) ------------------- @@ -118,7 +114,6 @@ Breaking changes / important additions: annotation isolation. There should be no more side effects from arbitrarily mixing and matching the decorators. - Improved handling of completely empty serializers with COMPONENT_SPLIT_REQUEST. - 0.20.1 (2021-10-03) ------------------- @@ -130,7 +125,6 @@ Breaking changes / important additions: - Hotfix release due to regression in the Redoc template - 0.20.0 (2021-10-01) ------------------- @@ -140,8 +134,8 @@ Breaking changes / important additions: - Add arbitrarily deep ListSerializer nesting `#539 `_ - tighten serializer assumptions `#539 `_ - fix whitespace stripping on methods -- Rename `AutoSchema._map_field_validators()` → `.insert_field_validators()`. [Nick Pope] -- Rename `AutoSchema._map_min_max()` → `.insert_min_max()`. [Nick Pope] +- Rename ``AutoSchema._map_field_validators()`` → ``.insert_field_validators()``. [Nick Pope] +- Rename ``AutoSchema._map_min_max()`` → ``.insert_min_max()``. [Nick Pope] - Fix detection of int64 from min/max values. [Nick Pope] - Fix zero handling in _map_min_max(). [Nick Pope] - Add support for introspection of nested validators. [Nick Pope] @@ -157,10 +151,9 @@ Breaking changes / important additions: - Added vendor specification extensions - Completetly overhauled validator logic and bugfixes -- Offline UI assets with optional ``drf-spectacular-sidecar`` package +- Offline UI assets with optional *drf-spectacular-sidecar* package - several internal logic improvements and stricter assumptions - 0.19.0 (2021-09-21) ------------------- @@ -206,10 +199,9 @@ Breaking changes / important additions: - Severely improved path parameter detection for Django-style parameters, RE parameters, and custom converters - Significantly more defensive settings loading for safer project imports (less prone to import loops) - Improved type hint support for ``Enum`` and other native types -- Explicit support for ``drf-nested-routers`` +- Explicit support for *drf-nested-routers* - A lot more small improvements - 0.18.2 (2021-09-04) ------------------- @@ -222,7 +214,6 @@ Breaking changes / important additions: - Primarily ironing out another issue with the Django check and some minor improvements - 0.18.1 (2021-08-31) ------------------- @@ -239,7 +230,6 @@ Breaking changes / important additions: - Check also moved into the ``--deploy`` section to prevent double execution. This can be disabled with ``ENABLE_DJANGO_DEPLOY_CHECK`` - Facitities added to utilize SwaggerUI Topbar for versioning. - 0.18.0 (2021-08-25) ------------------- @@ -260,10 +250,9 @@ Breaking changes / important additions: Breaking changes / important additions: - This is a y-stream release because we added `Django checks `_ - which might emit warnings and subsequently break CI. This can be easily suppressed with Django's `SILENCED_SYSTEM_CHECKS`. + which might emit warnings and subsequently break CI. This can be easily suppressed with Django's ``SILENCED_SYSTEM_CHECKS``. - Several small fixes and features that should not have a big impact. - 0.17.3 (2021-07-26) ------------------- @@ -283,7 +272,6 @@ Breaking changes / important additions: - Just a few bugfixes and some small features with minimal impact on existing schema - 0.17.2 (2021-06-15) ------------------- @@ -293,10 +281,9 @@ Breaking changes / important additions: Breaking changes / important additions: -- Hotfix release that addresses a carelessly added import in `0.17.1`. In certain use-cases, +- Hotfix release that addresses a carelessly added import in 0.17.1. In certain use-cases, this may have led to an import cycle inside DRF. - 0.17.1 (2021-06-12) ------------------- @@ -314,7 +301,6 @@ Breaking changes / important additions: - This release is mainly for fixing incomplete type hints which mypy will potentially complain about. - A few small fixes that should either have no or a very small impact in schemas. - 0.17.0 (2021-06-01) ------------------- @@ -337,7 +323,6 @@ Breaking changes / important additions: This should have no negative impact, but to be on the safe side we'll opt for a y-stream release. - The package is now marked as being typed, which should get picked up natively by mypy - 0.16.0 (2021-05-10) ------------------- @@ -369,7 +354,6 @@ Breaking changes / important additions: - minor release to fix newly introduced default prefix estimation. - 0.15.0 (2021-04-03) ------------------- @@ -395,11 +379,10 @@ Breaking changes / important additions: - New default ``None`` for ``SCHEMA_PATH_PREFIX`` will attempt to determine a reasonable prefix. Previous behavior is restored with ``''`` - Added ``OpenApiResponses`` to gain access to response object descriptions. - 0.14.0 (2021-03-09) ------------------- -- Fixed bug with `cached_property` non-Model objects not being traversed [Luke Plant] +- Fixed bug with ``cached_property`` non-Model objects not being traversed [Luke Plant] - Fixed issue `#314 `_ - include information about view/serializer in warnings. [Luke Plant] - bugfix forward/reverse model traversal `#323 `_ - fix nested serializer detection & smarter metadata extraction `#319 `_ @@ -432,14 +415,13 @@ Breaking changes / important additions: Breaking changes / important additions: -- `drf-spectacular`'s custom ``DjangoFilterBackend`` removed after previous deprecation. Just use the original class again. -- ``django-filter`` extension received a significant refactoring so your schema may have several changes, hopefully positive ones. +- *drf-spectacular*'s custom ``DjangoFilterBackend`` removed after previous deprecation. Just use the original class again. +- *django-filter* extension received a significant refactoring so your schema may have several changes, hopefully positive ones. - Added response headers feature - Extended ``@extend_schema(request=X)``, where ``X`` may now also be a ``Dict[content_type, serializer_etc]`` - Updated Swagger UI version - Fixed several model traveral issues that may lead to PK changes in the schema -- Added `drf-yasg's` ``swagger_fake_view`` - +- Added *drf-yasg*'s ``swagger_fake_view`` 0.13.2 (2021-02-11) ------------------- @@ -460,7 +442,6 @@ Breaking changes / important additions: - fix readonly related fields generating incorrect schema `#274 `_ [diesieben07] - bugfix save parameter removal `#212 `_ - 0.13.1 (2021-01-21) ------------------- @@ -473,7 +454,6 @@ Breaking changes / important additions: - Update README.rst [Chad Ramos] - Create new mock request on each operation [Matthias Erll] - 0.13.0 (2021-01-13) ------------------- @@ -491,8 +471,7 @@ Breaking changes / important additions: Breaking changes: -- several small improvements that should not have a big impact. this is a y-stream release mainly due to schema changes that may occur with ``django-filter``. - +- several small improvements that should not have a big impact. this is a y-stream release mainly due to schema changes that may occur with *django-filter*. 0.12.0 (2020-12-19) ------------------- @@ -516,7 +495,7 @@ Breaking changes: Breaking changes: -- reverted back to ``0.10.0`` Swagger UI behavior as default. Users relying on stricter CSP should use ``SpectacularSwaggerSplitView`` +- reverted back to *0.10.0* Swagger UI behavior as default. Users relying on stricter CSP should use ``SpectacularSwaggerSplitView`` - ``tokenAuth`` slightly changed to properly model correct ``Authorization`` header - a lot of minor improvements that may slightly alter the schema @@ -629,7 +608,7 @@ Breaking changes: ------------------- - Temporarily pin the swagger-ui unpkg URL to 3.30.0 [Mohamed Abdulaziz] -- Add `deepLinking` parameter [p.alekseev] +- Add ``deepLinking`` parameter [p.alekseev] - added preprocessing hooks for operation list modification/filtering `#93 `_ - Document effective DRF settings [John Vandenberg] - add format query parameter `#110 `_ @@ -763,7 +742,7 @@ Breaking changes: - explicit override for non-list serializers on ViewSet list `#49 `_ - improve model field mapping via DRF init logic - bugfix enum substitution with additional field parameters. -- Fix getting default parameter for `MultipleChoiceField` [p.alekseev] +- Fix getting default parameter for ``MultipleChoiceField`` [p.alekseev] - bugfix model path traversal via intermediate property - try to be more graceful with unknown custom model fields. `#33 `_ @@ -788,13 +767,12 @@ Breaking changes: - Parse path parameter type hints from url. closes `#34 `_ - Consolidate duplicate warnings/add error `#28 `_ - Prevent warning for DRF format suffix param -- Improve ACCEPT header handling `#42 `_ +- Improve ACCEPT header handling `#42 `_ Breaking changes: - all extension base classes moved to ``drf_spectacular.extensions`` - 0.9.2 (2020-04-27) ------------------ @@ -846,7 +824,7 @@ Breaking changes: Breaking changes: -- removed `to_schema()` from `OpenApiParameter`. Handled in ``AutoSchema`` now. +- removed ``to_schema()`` from ``OpenApiParameter``. Handled in ``AutoSchema`` now. 0.8.8 (2020-03-21) ------------------ @@ -868,7 +846,7 @@ Breaking changes: - Warn on duplicate serializer names. - Added explicit exclude flag for operation. - Bugfix: PrimaryKeyRelatedField(read_only=True) failing to find type. -- Change operation sorting to alphanumeric with option (`#6 `_) +- Change operation sorting to alphanumeric with option (`#6 `_) - Robustify serializer field support for ``@extend_schema_field``. - Enable field serializers support. [p.g.alekseev] - Adding custom tags support [p.g.alekseev] @@ -885,14 +863,15 @@ Breaking changes: 0.8.5 (2020-03-08) ------------------ + - Generalize ``PolymorphicResponse`` into ``PolymorphicProxySerializer``. - Type dict is resolved as object. - Simplify hint resolution. - Allow ``@extend_schema_field`` for custom serializer fields. - 0.8.4 (2020-03-06) ------------------ + - ``@extend_schema_field`` accepts Serializers and OpenApiTypes - Generalize query parameter. - Bugfix serializer init. @@ -901,21 +880,20 @@ Breaking changes: - Helper scripts for swagger and generator. - Fix license. - 0.8.3 (2020-03-02) ------------------ + - Fix parameter type resolution. - Remove empty parameters. - Improved assert message. - 0.8.2 (2020-03-02) ------------------ + - Working release. - Bugfix wrong call & remove yaml aliases. - 0.8.1 (2020-03-01) ------------------ -- Initial published version. +- Initial published version. diff --git a/README.rst b/README.rst index 4c03c467..e182baa3 100644 --- a/README.rst +++ b/README.rst @@ -37,7 +37,7 @@ Features - Callback operations (experimental) - Included support for: - `django-polymorphic `_ / `django-rest-polymorphic `_ - - `SimpleJWT `_ + - `SimpleJWT `_ - `DjangoOAuthToolkit `_ - `djangorestframework-jwt `_ (tested fork `drf-jwt `_) - `dj-rest-auth `_ (maintained fork of `django-rest-auth `_) @@ -48,7 +48,7 @@ Features - `djangorestframework-dataclasses `_ -For more information visit the `documentation `_. +For more information visit the `documentation `_. License ------- @@ -135,7 +135,7 @@ these static files as a separate optional package. Usage is as follows: Release management ^^^^^^^^^^^^^^^^^^ -`drf-spectacular` deliberately stays below version ``1.x.x`` to signal that every +*drf-spectacular* deliberately stays below version *1.x.x* to signal that every new version may potentially break you. For production we strongly recommend pinning the version and inspecting a schema diff on update. @@ -143,8 +143,8 @@ With that said, we aim to be extremely defensive w.r.t. breaking API changes. Ho we also acknowledge the fact that even slight schema changes may break your toolchain, as any existing bug may somehow also be used as a feature. -We define version increments with the following semantics. `y-stream` increments may contain -potentially breaking changes to both API and schema. `z-stream` increments will never break the +We define version increments with the following semantics. *y-stream* increments may contain +potentially breaking changes to both API and schema. *z-stream* increments will never break the API and may only contain schema changes that should have a low chance of breaking you. @@ -158,8 +158,8 @@ Generate your schema with the CLI: $ ./manage.py spectacular --file schema.yml $ docker run -p 80:8080 -e SWAGGER_JSON=/schema.yml -v ${PWD}/schema.yml:/schema.yml swaggerapi/swagger-ui -If you also want to validate your schema add the `--validate` flag. Or serve your schema directly -from your API. We also provide convenience wrappers for `swagger-ui` or `redoc`. +If you also want to validate your schema add the ``--validate`` flag. Or serve your schema directly +from your API. We also provide convenience wrappers for ``swagger-ui`` or ``redoc``. .. code:: python @@ -175,7 +175,7 @@ from your API. We also provide convenience wrappers for `swagger-ui` or `redoc`. Usage ----- -`drf-spectacular` works pretty well out of the box. You might also want to set some metadata for your API. +*drf-spectacular* works pretty well out of the box. You might also want to set some metadata for your API. Just create a ``SPECTACULAR_SETTINGS`` dictionary in your ``settings.py`` and override the defaults. Have a look at the `available settings `_. @@ -288,16 +288,16 @@ globally, and then simply run: $ tox .. _Django REST framework: https://www.django-rest-framework.org/ -.. _OpenAPI 3.0: https://github.com/OAI/OpenAPI-Specification -.. _tox: http://tox.readthedocs.org/en/latest/ +.. _OpenAPI 3.0: https://spec.openapis.org/oas/v3.0.3 +.. _tox: https://tox.wiki/ .. _drf-spectacular-sidecar: https://github.com/tfranzel/drf-spectacular-sidecar .. |build-status| image:: https://github.com/tfranzel/drf-spectacular/actions/workflows/ci.yml/badge.svg :target: https://github.com/tfranzel/drf-spectacular/actions/workflows/ci.yml .. |pypi-version| image:: https://img.shields.io/pypi/v/drf-spectacular.svg - :target: https://pypi.python.org/pypi/drf-spectacular -.. |codecov| image:: https://codecov.io/gh/tfranzel/drf-spectacular/branch/master/graph/badge.svg - :target: https://codecov.io/gh/tfranzel/drf-spectacular + :target: https://pypi.org/project/drf-spectacular/ +.. |codecov| image:: https://app.codecov.io/gh/tfranzel/drf-spectacular/branch/master/graph/badge.svg + :target: https://app.codecov.io/gh/tfranzel/drf-spectacular .. |docs| image:: https://readthedocs.org/projects/drf-spectacular/badge/ :target: https://drf-spectacular.readthedocs.io/ .. |pypi-dl| image:: https://img.shields.io/pypi/dm/drf-spectacular diff --git a/docs/blueprints.rst b/docs/blueprints.rst index 53a2e363..dfdb4e76 100644 --- a/docs/blueprints.rst +++ b/docs/blueprints.rst @@ -4,7 +4,7 @@ Extension Blueprints ==================== Blueprints are a collection of schema fixes for Django and REST Framework apps. -Some libraries/apps do not play well with `drf-spectacular`'s automatic introspection. +Some libraries/apps do not play well with *drf-spectacular*'s automatic introspection. With extensions you can manually provide the necessary information to generate a better schema. There is no blueprint for the app you are looking for? No problem, you can easily write extensions @@ -39,7 +39,7 @@ djangorestframework-api-key --------------------------- Since `djangorestframework-api-key `_ has -no entry in ``authentication_classes``, `drf-spectacular` cannot pick up this library. To alleviate +no entry in ``authentication_classes``, *drf-spectacular* cannot pick up this library. To alleviate this shortcoming, you can manually add the appropriate security scheme. .. note:: Usage of the ``SECURITY`` setting is discouraged, unless there are special circumstances @@ -97,7 +97,7 @@ drf-rw-serializers `drf-rw-serializers`__ provides generic views, viewsets and mixins that extend the Django REST Framework ones adding separated serializers for read and write operations. -`drf-spectacular` requires just a small ``AutoSchema`` augmentation to make it aware of +*drf-spectacular* requires just a small ``AutoSchema`` augmentation to make it aware of ``drf-rw-serializers``. Remember to replace the ``AutoSchema`` in ``DEFAULT_SCHEMA_CLASS``. __ https://github.com/vintasoftware/drf-rw-serializers diff --git a/docs/changelog.rst b/docs/changelog.rst index 4d7817ae..565b0521 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1 +1 @@ -.. include:: ../CHANGELOG.rst \ No newline at end of file +.. include:: ../CHANGELOG.rst diff --git a/docs/client_generation.rst b/docs/client_generation.rst index 933576fe..8b98f8ac 100644 --- a/docs/client_generation.rst +++ b/docs/client_generation.rst @@ -1,9 +1,9 @@ .. _client_generation: Client generation -=============================== +================= -`drf-spectacular` aims to generate the most accurate schema possible under the constraints of OpenAPI 3.0.3. +*drf-spectacular* aims to generate the most accurate schema possible under the constraints of OpenAPI 3.0.3. Unfortunately, sometimes this goal conflicts with generating a good and functional client. To serve the two main use cases, i.e. documenting the API and generating clients, we opt for getting the @@ -12,7 +12,7 @@ most accurate schema first, and then provide settings that allow to resolve pote .. note:: TL;DR - Simply setting ``'COMPONENT_SPLIT_REQUEST': True`` will most likely yield the best and most accurate client. -.. note:: `drf-spectacular` generates warnings where it recognizes potential problems. Some warnings +.. note:: *drf-spectacular* generates warnings where it recognizes potential problems. Some warnings are important to having a correct client. Fixing all warning is highly recommended. .. note:: For generating clients with CI, we highly recommend using @@ -49,8 +49,6 @@ Relevant settings: # Create separate components for PATCH endpoints (without required list) 'COMPONENT_SPLIT_PATCH': True, - - Enum issues ----------- @@ -59,8 +57,11 @@ field. Even though it is the correct way (according to the specification), it sa Setting ``'ENUM_ADD_EXPLICIT_BLANK_NULL_CHOICE': False`` will create a less accurate schema that tends to offend fewer generator targets. -For more information please refer to the `official documentation `_ and -more specifically the `specification proposal `_. +For more information please refer to the `official documentation`__ and more specifically the `specification +proposal`__. + +__ https://swagger.io/docs/specification/data-models/enums/ +__ https://github.com/OAI/OpenAPI-Specification/blob/main/proposals/2019-10-31-Clarify-Nullable.md#user-content-if-a-schema-specifies-nullable-true-and-enum-1-2-3-does-that-schema-allow-null-values-see-1900 Relevant settings: @@ -69,7 +70,6 @@ Relevant settings: # Adds "blank" and "null" enum choices where appropriate. disable on client generation issues 'ENUM_ADD_EXPLICIT_BLANK_NULL_CHOICE': True, - Type issues ----------- diff --git a/docs/conf.py b/docs/conf.py index 9e2ae11f..6435ef63 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -17,7 +17,7 @@ settings.configure(USE_I18N=False, USE_L10N=False) -sys.path.insert(0, os.path.abspath('../')) +sys.path[:0] = [os.path.abspath('../'), os.path.abspath('./')] # -- Project information ----------------------------------------------------- @@ -33,6 +33,7 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + 'extensions', 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', ] @@ -45,6 +46,22 @@ # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +default_role = 'default-role-error' + +linkcheck_allowed_redirects = { + r"^https://tox\.wiki/$": r"https://tox\.wiki/en/latest/$", + r"^https://drf-spectacular\.readthedocs\.io/$": r"https://drf-spectacular\.readthedocs\.io/en/latest/$", + r"^https://docs\.djangoproject\.com/en/stable/": r"^https://docs\.djangoproject\.com/en/\d+\.\d+/", + r"^https://github\.com/tfranzel/drf-spectacular/issues/\d+": "https://github\.com/tfranzel/drf-spectacular/pull/\d+", +} + +linkcheck_ignore = [ + # Special-use addresses and domain names. (RFC 6761/6890) + r"^https?://(?:127\.0\.0\.1|\[::1\])(?::\d+)?/", + r"^https?://(?:[^/\.]+\.)*example\.(?:com|net|org)(?::\d+)?/", + r"^https?://(?:[^/\.]+\.)*(?:example|invalid|localhost|test)(?::\d+)?/", +] + nitpicky = True nitpick_ignore_regex = [ diff --git a/docs/customization.rst b/docs/customization.rst index b14a0100..cfc14acc 100644 --- a/docs/customization.rst +++ b/docs/customization.rst @@ -7,20 +7,22 @@ You are not satisfied with your generated schema? Follow these steps in order to schema closer to your API. .. note:: The warnings emitted by ``./manage.py spectacular --file schema.yaml --validate`` - are intended as an indicator to where `drf-spectacular` discovered issues. + are intended as an indicator to where *drf-spectacular* discovered issues. Sane fallbacks are used wherever possible and some warnings might not even be relevant to you. The remaining issues can be solved with the following steps. Step 1: ``queryset`` and ``serializer_class`` --------------------------------------------- + Introspection heavily relies on those two attributes. ``get_serializer_class()`` and ``get_serializer()`` are also used if available. You can also set those -on ``APIView``. Even though this is not supported by DRF, `drf-spectacular` will pick +on ``APIView``. Even though this is not supported by DRF, *drf-spectacular* will pick them up and use them. Step 2: :py:class:`@extend_schema ` ------------------------------------------------------------------------ + Decorate your view functions with the :py:func:`@extend_schema ` decorator. There is a multitude of override options, but you only need to override what was not properly discovered in the introspection. @@ -78,7 +80,8 @@ discovered in the introspection. Step 3: :py:class:`@extend_schema_field ` and type hints --------------------------------------------------------------------------------------------------- -A custom ``SerializerField`` might not get picked up properly. You can inform `drf-spectacular` + +A custom ``SerializerField`` might not get picked up properly. You can inform *drf-spectacular* on what is to be expected with the :py:func:`@extend_schema_field ` decorator. It takes either basic types or a ``Serializer`` as argument. In case of basic types (e.g. ``str``, ``int``, etc.) a type hint is already sufficient. @@ -90,7 +93,6 @@ decorator. It takes either basic types or a ``Serializer`` as argument. In case def to_representation(self, value): return urlsafe_base64_encode(b'\xf0\xf1\xf2') - You can apply it also to the method of a ``SerializerMethodField``. .. code-block:: python @@ -102,9 +104,8 @@ You can apply it also to the method of a ``SerializerMethodField``. def get_field_custom(self, object): return '2020-03-06 20:54:00.104248' - Step 4: :py:class:`@extend_schema_serializer ` ------------------------------------------------------------------------------------------------ +---------------------------------------------------------------------------------------------- You may also decorate your serializer with :py:func:`@extend_schema_serializer `. Mainly used for excluding specific fields from the schema or attaching request/response examples. @@ -136,15 +137,15 @@ On rare occasions (e.g. envelope serializers), overriding list detection with `` fields = '__all__' model = Album - Step 5: Extensions ------------------ + The core purpose of extensions is to make the above customization mechanisms also available for library code. Usually, you cannot easily decorate or modify ``View``, ``Serializer`` or ``Field`` from libraries. Extensions provide a way to hook into the introspection without actually touching the library. All extensions work on the same principle. You provide a ``target_class`` (import path -string or actual class) and then state what `drf-spectcular` should use instead of what +string or actual class) and then state what *drf-spectcular* should use instead of what it would normally discover. .. note:: The extensions register themselves automatically. Just be sure that the Python @@ -160,8 +161,9 @@ it would normally discover. Replace views with :py:class:`OpenApiViewExtension ` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Many libraries use ``@api_view`` or ``APIView`` instead of `ViewSet` or `GenericAPIView`. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Many libraries use ``@api_view`` or ``APIView`` instead of ``ViewSet`` or ``GenericAPIView``. In those cases, introspection has very little to work with. The purpose of this extension is to augment or switch out the encountered view (only for schema generation). Simply extending the discovered class ``class Fixed(self.target_class)`` with a ``queryset`` or @@ -180,7 +182,7 @@ the discovered class ``class Fixed(self.target_class)`` with a ``queryset`` or return Fixed Specify authentication with :py:class:`OpenApiAuthenticationExtension ` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _customization_authentication_extension: @@ -204,8 +206,9 @@ A simple custom HTTP header based authentication could be achieved like this: Declare field output with :py:class:`OpenApiSerializerFieldExtension ` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This is mainly targeted to custom `SerializerField`'s that are within library code. This extension +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This is mainly targeted to custom ``SerializerField``'s that are within library code. This extension is functionally equivalent to :py:func:`@extend_schema_field ` .. code-block:: python @@ -219,19 +222,20 @@ is functionally equivalent to :py:func:`@extend_schema_field ` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This is one of the more involved extension mechanisms. `drf-spectacular` uses those to implement +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This is one of the more involved extension mechanisms. *drf-spectacular* uses those to implement `polymorphic serializers `_. The usage of this extension is rarely necessary because most custom ``Serializer`` classes stay very close to the default behaviour. Declare custom/library filters with :py:class:`OpenApiFilterExtension ` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This extension only applies to filter and pagination classes and is rarely used. Built-in support for -`django-filters` is realized with this extension. :py:class:`OpenApiFilterExtension ` +*django-filter* is realized with this extension. :py:class:`OpenApiFilterExtension ` replaces the filter's native ``get_schema_operation_parameters`` with your customized version, where you -have full access to `drf-spectacular's` more advanced introspection features. - +have full access to *drf-spectacular*'s more advanced introspection features. Step 6: Postprocessing hooks ---------------------------- @@ -247,9 +251,9 @@ the choice ``Enum`` are consolidated into component objects. You can register ad # your modifications to the schema in parameter result return result - Step 7: Preprocessing hooks --------------------------- + .. _customization_preprocessing_hooks: Preprocessing hooks are applied shortly after collecting all API operations and before the @@ -266,7 +270,6 @@ additional hooks with the ``PREPROCESSING_HOOKS`` setting. pass return endpoints - .. note:: A common use case would be the removal of duplicated ``{format}``-suffixed operations, for which we already provide the :py:func:`drf_spectacular.hooks.preprocess_exclude_path_format ` diff --git a/docs/drf_yasg.rst b/docs/drf_yasg.rst index 501d2e3b..508d6d29 100644 --- a/docs/drf_yasg.rst +++ b/docs/drf_yasg.rst @@ -1,20 +1,19 @@ -From `drf-yasg` to OpenAPI 3 +From *drf-yasg* to OpenAPI 3 ============================ `drf-yasg`__ is an excellent library and the most popular choice for generating OpenAPI 2.0 (formerly known as Swagger 2.0) schemas with `Django REST Framework`__. Unfortunately, it currently does not provide support for OpenAPI 3.x. -Migration from ``drf-yasg`` to ``drf-spectacular`` requires some modifications, the complexity of which depends on what +Migration from *drf-yasg* to *drf-spectacular* requires some modifications, the complexity of which depends on what features are being used. __ https://pypi.org/project/drf-yasg __ https://pypi.org/project/djangorestframework/ -.. note:: In contrast to `drf-yasg`, we don't package Redoc & Swagger UI but serve them via hyperliked CDNs instead. +.. note:: In contrast to *drf-yasg*, we don't package Redoc & Swagger UI but serve them via hyperlinked CDNs instead. If you want or need to serve those files yourself, you can do that with the optional - `drf-spectacular-sidecar `_. See + `drf-spectacular-sidecar `_ package. See :ref:`installation instructions ` for further details. - Decorators ---------- @@ -29,7 +28,7 @@ Decorators - Use ``None`` instead of :py:class:`drf_yasg.utils.no_body` - - ``method`` argument doesn't exist, use ``methods`` instead (also supported by ``drf-yasg``) + - ``method`` argument doesn't exist, use ``methods`` instead (also supported by *drf-yasg*) - ``auto_schema`` has no equivalent. - ``extra_overrides`` has no equivalent. - ``field_inspectors`` has no equivalent. @@ -48,7 +47,7 @@ Decorators - Instead of using :py:func:`@method_decorator `, use :py:func:`@extend_schema_view `. -- Instead of using `swagger_schema_field`, use +- Instead of using ``swagger_schema_field``, use :py:func:`@extend_schema_field ` or :py:func:`@extend_schema_serializer `. @@ -67,7 +66,7 @@ Helper Classes - ``schema`` argument is called ``response`` - Order of arguments differs, so use keyword arguments. -- :py:class:`~drf_spectacular.utils.OpenApiExample` is available for providing ``examples`` to +- :py:class:`~drf_spectacular.utils.OpenApiExample` is available for providing ``examples`` to :py:func:`@extend_schema `. - :py:class:`~drf_yasg.openapi.Schema` is not required and can be eliminated. Use a plain :py:class:`dict` instead. @@ -154,17 +153,16 @@ Parameter Location - :py:data:`~drf_yasg.openapi.IN_QUERY` is called :py:attr:`~drf_spectacular.utils.OpenApiParameter.QUERY` - :py:data:`~drf_yasg.openapi.IN_HEADER` is called :py:attr:`~drf_spectacular.utils.OpenApiParameter.HEADER` - :py:data:`~drf_yasg.openapi.IN_BODY` and :py:data:`~drf_yasg.openapi.IN_FORM` have no direct equivalent. - Instead you can use ``@extend_schema(request={"": ...})`` or - ``@extend_schema(request={("", "": ...})``. - :py:attr:`~drf_spectacular.utils.OpenApiParameter.COOKIE` is also available. Docstring Parsing ----------------- -``drf-yasg`` has some special handling for docstrings that is not supported by ``drf-spectacular``. +*drf-yasg* has some special handling for docstrings that is not supported by *drf-spectacular*. It attempts to split the first line from the rest of the docstring to use as the operation summary, and the remainder -is used as the operation description. ``drf-spectacular`` uses the entire docstring as the description. Use the +is used as the operation description. *drf-spectacular* uses the entire docstring as the description. Use the ``summary`` and ``description`` arguments of :py:func:`@extend_schema ` instead. Optionally, the docstring can still be used to populate the operation description. @@ -196,7 +194,7 @@ Optionally, the docstring can still be used to populate the operation descriptio """Return a list of all usernames in the system.""" ... -In addition, ``drf-yasg`` also supports `named sections`__, but these are not supported by ``drf-spectacular``. Again, +In addition, *drf-yasg* also supports `named sections`__, but these are not supported by *drf-spectacular*. Again, use the ``summary`` and ``description`` arguments of :py:func:`@extend_schema ` instead: @@ -236,9 +234,9 @@ __ https://www.django-rest-framework.org/coreapi/schemas/#schemas-as-documentati Authentication -------------- -In ``drf-yasg`` it was necessary to :doc:`manually describe authentication schemes `. +In *drf-yasg* it was necessary to :doc:`manually describe authentication schemes `. -In ``drf-spectacular`` there is support for auto-generating the security definitions for a number of authentication +In *drf-spectacular* there is support for auto-generating the security definitions for a number of authentication classes built in to DRF as well as other popular third-party packages. :py:class:`~drf_spectacular.extensions.OpenApiAuthenticationExtension` is available to help tie in custom authentication clasees -- see the :ref:`customization guide `. @@ -246,7 +244,7 @@ authentication clasees -- see the :ref:`customization guide `_. - I cannot use :py:func:`@extend_schema ` on library code -------------------------------------------------------------------------------------------- -You can easily adapt introspection for libraries/apps with the ``Extension`` mechanism. -``Extensions`` provide an easy way to attach schema information to code that you cannot -modify otherwise. Have a look at :ref:`customization` on how to use ``Extensions`` +You can easily adapt introspection for libraries/apps with the *Extension* mechanism. +*Extensions* provide an easy way to attach schema information to code that you cannot +modify otherwise. Have a look at :ref:`customization` on how to use *Extensions* I get an empty schema or endpoints are missing ---------------------------------------------- + This is usually due versioning (or more rarely due to permisssions). In case you use versioning on all endpoints, that might be the intended output. @@ -35,25 +36,25 @@ This will contain unversioned endpoints together with the endpoints for the the For the schema views you can either set a versioning class (implicit versioning via the request) or explicitly override the version with ``SpectacularAPIView.as_view(api_version='YOUR_VERSION')``. - I expected a different schema ----------------------------- + Sometimes views declare one thing (via ``serializer_class`` and ``queryset``) and do a entirely different thing. Usually this is attributed to making a library code flexible under varying situations. In those cases it is best to override what the introspection decuded and state explicitly what is to be expected. Work through the steps in :ref:`customization` to adapt your schema. - I get duplicated operations with a ``{format}``-suffix ------------------------------------------------------ + Your app likely uses DRF's ``format_suffix_patterns``. If those operations are undesireable in your schema, you can simply exclude them with an already provided :ref:`preprocessing hook `. - I get a lot of warnings ----------------------- + The warnings are emitted to inform you of discovered schema issues. Some usage patterns like ``@api_view`` or ``APIView`` provide very little discoverable information on your API. In those cases you can @@ -61,9 +62,9 @@ easily augment those endpoints and serializers with additional information. Look at :ref:`customization` options to fill those gaps and make the warnings disappear. - I get warnings regarding my ``Enum`` or my ``Enum`` names have a weird suffix -------------------------------------------------------------------------------- +------------------------------------------------------------------------------ + This is because the ``Enum`` postprocessing hook is activated by default, which attempts to find a name for a set of enum choices. @@ -105,7 +106,6 @@ For example: If you have multiple semantically distinct enums that happen to have the same set of values, and you want different names for them, this mechanism won't work. - My endpoints use different serializers depending on the situation ----------------------------------------------------------------- @@ -128,16 +128,15 @@ like so: def retrieve(self, request, *args, **kwargs) pass - My authentication method is not supported ----------------------------------------- + You can easily specify a custom authentication with :py:class:`OpenApiAuthenticationExtension `. -Have a look at :ref:`customization` on how to use ``Extensions`` - +Have a look at :ref:`customization` on how to use *Extensions* How can I i18n/internationalize my schema and UI? ----------------------------------------------------- +------------------------------------------------- You can use the Django internationalization as you would normally do. The workflow is as one would expect: ``USE_I18N=True``, settings the languages, ``makemessages``, and ``compilemessages``. @@ -161,9 +160,9 @@ falls back to the default language. def retrieve(self, request, *args, **kwargs) pass - FileField (ImageField) is not handled properly in the schema ------------------------------------------------------------ + In contrast to most other fields, ``FileField`` behaves differently for requests and responses. This duality is impossible to represent in a single component schema. @@ -172,10 +171,9 @@ by setting ``COMPONENT_SPLIT_REQUEST = True``. Note that this influences the who not just components with ``FileFields``. Also consider explicitly setting ``parser_classes = [parsers.MultiPartParser]`` (or any file compatible parser) -on your `View` or write a custom `get_parser_classes`. These fields do not work with the default ``JsonParser`` +on your ``View`` or write a custom ``get_parser_classes``. These fields do not work with the default ``JsonParser`` and that fact should be represented in the schema. - I'm using ``@action(detail=False)`` but the response schema is not a list ------------------------------------------------------------------------- @@ -184,7 +182,6 @@ The ``detail`` parameter in itself makes no statement about the action's respons for underspecified endpoints is a non-list response. To signal a listed response, you can use ``@extend_schema(responses=XSerializer(many=True))``. - Using ``@extend_schema`` on ``APIView`` has no effect ----------------------------------------------------- @@ -202,17 +199,16 @@ The extensions register themselves automatically. Just be sure that the python i To that end, we suggest creating a ``PROJECT/schema.py`` file and importing it in your ``PROJECT/__init__.py`` (same directory as ``settings.py`` and ``urls.py``) with ``import PROJECT.schema``. - My ``@action`` is erroneously paginated or has filter parameters that I do not want ----------------------------------------------------------------------------------- This usually happens when ``@extend_schema(responses=XSerializer(many=True))`` is used. Actions inherit filter and pagination classes from their ``ViewSet``. If the response is then marked as a list, the ``pagination_class`` kicks in. Since actions are handled manually by the user, this behavior is usually not immediately obvious. -To make make your intentions clear to `drf-spectacular`, you need to clear the offening classes in the action +To make make your intentions clear to *drf-spectacular*, you need to clear the offening classes in the action decorator, e.g. setting ``pagination_class=None``. -Users of ``django-filter`` might also see unwanted query parameters. Since the same mechanics apply here too, +Users of *django-filter* might also see unwanted query parameters. Since the same mechanics apply here too, you can remove those parameters by resetting the filter backends with ``@action(...,filter_backends=[])``. .. code-block:: python @@ -226,7 +222,6 @@ you can remove those parameters by resetting the filter backends with ``@action( def custom_action(self): pass - How to I wrap my responses? / My endpoints are wrapped in a generic envelope ---------------------------------------------------------------------------- @@ -258,7 +253,6 @@ Adapt to your specific requirements. def list(self, request, *args, **kwargs): ... - How can I have multiple ``SpectacularAPIView`` with differing settings ---------------------------------------------------------------------- @@ -285,7 +279,6 @@ not allowed. ``SpectacularAPIView`` has dedicated arguments for overriding these ), name='schema-custom'), ] - How to correctly annotate function-based views that use ``@api_view()`` ----------------------------------------------------------------------- @@ -313,7 +306,6 @@ and break down each case separately. def view_func(request, format=None): return ... - My ``get_queryset()`` depends on some attributes not available at schema generation time ---------------------------------------------------------------------------------------- diff --git a/docs/index.rst b/docs/index.rst index 2e1bae6f..44ab9379 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,16 +1,11 @@ -.. drf-spectacular documentation master file, created by - sphinx-quickstart on Sun Mar 1 22:11:53 2020. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - drf-spectacular =============== - `Sane and flexible OpenAPI 3 schema generation for Django REST framework.` +*Sane and flexible OpenAPI 3 schema generation for Django REST framework.* Documentation is an integral part of API development and OpenAPI 3 is finally here to make that process a easier. By using `drf-spectacular `_ -with `Django REST Framework (DRF) `_, +with `Django REST Framework (DRF) `_, your schema and therefore your documentation & client will always stay close to your API. drf-spectacular works well out of the box, but also provides you with several easy ways @@ -35,7 +30,6 @@ Table of Contents changelog.rst drf_spectacular.rst - Indices and Tables ------------------ diff --git a/docs/readme.rst b/docs/readme.rst index 7f1854e9..4dc0eb5d 100644 --- a/docs/readme.rst +++ b/docs/readme.rst @@ -1,3 +1,3 @@ .. _readme: -.. include:: ../README.rst \ No newline at end of file +.. include:: ../README.rst diff --git a/docs/settings.rst b/docs/settings.rst index 0ef4016a..3486b231 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -3,7 +3,6 @@ Settings ======== - Settings are configurable in ``settings.py`` in the scope ``SPECTACULAR_SETTINGS``. You can override any setting, otherwise the defaults below are used. @@ -12,7 +11,6 @@ You can override any setting, otherwise the defaults below are used. :start-after: APISettings :end-before: IMPORT_STRINGS - Django Rest Framework settings ------------------------------ @@ -37,9 +35,8 @@ The following are known to be effective: - ``SCHEMA_COERCE_PATH_PK`` - Example: SwaggerUI settings ----------------------------- +--------------------------- We currently support passing through all basic SwaggerUI `configuration parameters `_. For more customization options (e.g. JS functions), you can modify and override the diff --git a/drf_spectacular/extensions.py b/drf_spectacular/extensions.py index 9379d80b..8e4ed150 100644 --- a/drf_spectacular/extensions.py +++ b/drf_spectacular/extensions.py @@ -23,7 +23,7 @@ class OpenApiAuthenticationExtension(OpenApiGeneratorExtension['OpenApiAuthentic set a higher matching priority by setting the class attribute ``priority = 1`` or higher. ``get_security_definition()`` is expected to return a valid `OpenAPI security scheme object - `_ + `_ """ _registry: List['OpenApiAuthenticationExtension'] = [] @@ -46,12 +46,12 @@ class OpenApiSerializerExtension(OpenApiGeneratorExtension['OpenApiSerializerExt Extension for replacing an insufficient or specifying an unknown Serializer schema. The existing implementation of ``map_serializer()`` will generate the same result - as `drf-spectacular` would. Either augment or replace the generated schema. The + as *drf-spectacular* would. Either augment or replace the generated schema. The view instance is available via ``auto_schema.view``, while the original serializer can be accessed via ``self.target``. ``map_serializer()`` is expected to return a valid `OpenAPI schema object - `_. + `_. """ _registry: List['OpenApiSerializerExtension'] = [] @@ -68,13 +68,13 @@ class OpenApiSerializerFieldExtension(OpenApiGeneratorExtension['OpenApiSerializ """ Extension for replacing an insufficient or specifying an unknown SerializerField schema. - To augment the default schema, you can get what `drf-spectacular` would generate with + To augment the default schema, you can get what *drf-spectacular* would generate with ``auto_schema._map_serializer_field(self.target, direction, bypass_extensions=True)``. and edit the returned schema at your discretion. Beware that this may still emit warnings, in which case manual construction is advisable. ``map_serializer_field()`` is expected to return a valid `OpenAPI schema object - `_. + `_. """ _registry: List['OpenApiSerializerFieldExtension'] = [] @@ -119,7 +119,7 @@ class OpenApiFilterExtension(OpenApiGeneratorExtension['OpenApiFilterExtension'] ``get_schema_operation_parameters()`` is expected to return either an empty list or a list of valid raw `OpenAPI parameter objects - `_. + `_. Using ``drf_spectacular.plumbing.build_parameter_type`` is recommended to generate the appropriate raw dict objects. """ diff --git a/drf_spectacular/plumbing.py b/drf_spectacular/plumbing.py index 64d82f67..4d48c053 100644 --- a/drf_spectacular/plumbing.py +++ b/drf_spectacular/plumbing.py @@ -1058,7 +1058,7 @@ def sanitize_result_object(result): def sanitize_specification_extensions(extensions): - # https://spec.openapis.org/oas/v3.0.3#specification-extensions + # https://spec.openapis.org/oas/v3.0.3#specificationExtensions output = {} for key, value in extensions.items(): if not re.match(r'^x-', key): diff --git a/drf_spectacular/settings.py b/drf_spectacular/settings.py index fd43f53f..848b17cc 100644 --- a/drf_spectacular/settings.py +++ b/drf_spectacular/settings.py @@ -158,7 +158,7 @@ 'ENABLE_DJANGO_DEPLOY_CHECK': True, # General schema metadata. Refer to spec for valid inputs - # https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#openapi-object + # https://spec.openapis.org/oas/v3.0.3#openapi-object 'TITLE': '', 'DESCRIPTION': '', 'TOS': None, @@ -188,7 +188,7 @@ 'EXTENSIONS_ROOT': {}, # Oauth2 related settings. used for example by django-oauth2-toolkit. - # https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#oauth-flows-object + # https://spec.openapis.org/oas/v3.0.3#oauthFlowsObject 'OAUTH2_FLOWS': [], 'OAUTH2_AUTHORIZATION_URL': None, 'OAUTH2_TOKEN_URL': None, diff --git a/drf_spectacular/utils.py b/drf_spectacular/utils.py index 04cb52f0..5cb3c9a5 100644 --- a/drf_spectacular/utils.py +++ b/drf_spectacular/utils.py @@ -44,7 +44,7 @@ def create(self, request, *args, **kwargs): return Response(...) **Beware** that this is not a real serializer and it will raise an AssertionError - if used in that way. It **cannot** be used in views as `serializer_class` + if used in that way. It **cannot** be used in views as ``serializer_class`` or as field in an actual serializer. It is solely meant for annotation purposes. Also make sure that each sub-serializer has a field named after the value of @@ -61,7 +61,7 @@ def create(self, request, *args, **kwargs): It is **strongly** recommended to pass the ``Serializers`` as **list**, and by that let *drf-spectacular* retrieve the field and handle the mapping automatically. In special circumstances, the field may not available when - drf-spectacular processes the serializer. In those cases you can explicitly state + *drf-spectacular* processes the serializer. In those cases you can explicitly state the mapping with ``{'legal': LegalPersonSerializer, ...}``, but it is then your responsibility to have a valid mapping. """