Updates
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
from abc import abstractmethod
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union
|
||||
|
||||
from drf_spectacular.plumbing import OpenApiGeneratorExtension
|
||||
from drf_spectacular.utils import Direction
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from drf_spectacular.openapi import AutoSchema
|
||||
|
||||
|
||||
_SchemaType = Dict[str, Any]
|
||||
|
||||
|
||||
class OpenApiAuthenticationExtension(OpenApiGeneratorExtension['OpenApiAuthenticationExtension']):
|
||||
"""
|
||||
Extension for specifying authentication schemes.
|
||||
|
||||
The common use-case usually consists of setting a ``name`` string and returning a dict from
|
||||
``get_security_definition``. To model a group of headers that go together, set a list
|
||||
of names and return a corresponding list of definitions from ``get_security_definition``.
|
||||
|
||||
The view class is available via ``auto_schema.view``, while the original authentication class
|
||||
can be accessed via ``self.target``. If you want to override an included extension, be sure to
|
||||
set a higher matching priority by setting the class attribute ``priority = 1`` or higher.
|
||||
|
||||
get_security_requirement is expected to return a dict with security object names as keys and a
|
||||
scope list as value (usually just []). More than one key in the dict means that each entry is
|
||||
required (AND). If you need alternate variations (OR), return a list of those dicts instead.
|
||||
|
||||
``get_security_definition()`` is expected to return a valid `OpenAPI security scheme object
|
||||
<https://spec.openapis.org/oas/v3.0.3#security-scheme-object>`_
|
||||
"""
|
||||
_registry: List[Type['OpenApiAuthenticationExtension']] = []
|
||||
|
||||
name: Union[str, List[str]]
|
||||
|
||||
def get_security_requirement(
|
||||
self, auto_schema: 'AutoSchema'
|
||||
) -> Union[Dict[str, List[Any]], List[Dict[str, List[Any]]]]:
|
||||
assert self.name, 'name(s) must be specified'
|
||||
if isinstance(self.name, str):
|
||||
return {self.name: []}
|
||||
else:
|
||||
return {name: [] for name in self.name}
|
||||
|
||||
@abstractmethod
|
||||
def get_security_definition(self, auto_schema: 'AutoSchema') -> Union[_SchemaType, List[_SchemaType]]:
|
||||
pass # pragma: no cover
|
||||
|
||||
|
||||
class OpenApiSerializerExtension(OpenApiGeneratorExtension['OpenApiSerializerExtension']):
|
||||
"""
|
||||
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
|
||||
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
|
||||
<https://spec.openapis.org/oas/v3.0.3#schema-object>`_.
|
||||
"""
|
||||
_registry: List[Type['OpenApiSerializerExtension']] = []
|
||||
|
||||
def get_name(self, auto_schema: 'AutoSchema', direction: Direction) -> Optional[str]:
|
||||
""" return str for overriding default name extraction """
|
||||
return None
|
||||
|
||||
def get_identity(self, auto_schema: 'AutoSchema', direction: Direction) -> Any:
|
||||
""" return anything to compare instances of target. Target will be used by default. """
|
||||
return None
|
||||
|
||||
def map_serializer(self, auto_schema: 'AutoSchema', direction: Direction) -> _SchemaType:
|
||||
""" override for customized serializer mapping """
|
||||
return auto_schema._map_serializer(self.target_class, direction, bypass_extensions=True)
|
||||
|
||||
|
||||
class OpenApiSerializerFieldExtension(OpenApiGeneratorExtension['OpenApiSerializerFieldExtension']):
|
||||
"""
|
||||
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
|
||||
``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
|
||||
<https://spec.openapis.org/oas/v3.0.3#schema-object>`_.
|
||||
"""
|
||||
_registry: List[Type['OpenApiSerializerFieldExtension']] = []
|
||||
|
||||
def get_name(self) -> Optional[str]:
|
||||
""" return str for breaking out field schema into separate named component """
|
||||
return None
|
||||
|
||||
@abstractmethod
|
||||
def map_serializer_field(self, auto_schema: 'AutoSchema', direction: Direction) -> _SchemaType:
|
||||
""" override for customized serializer field mapping """
|
||||
pass # pragma: no cover
|
||||
|
||||
|
||||
class OpenApiViewExtension(OpenApiGeneratorExtension['OpenApiViewExtension']):
|
||||
"""
|
||||
Extension for replacing discovered views with a more schema-appropriate/annotated version.
|
||||
|
||||
``view_replacement()`` is expected to return a subclass of ``APIView`` (which includes
|
||||
``ViewSet`` et al.). The discovered original view instance can be accessed with
|
||||
``self.target`` and be subclassed if desired.
|
||||
"""
|
||||
_registry: List[Type['OpenApiViewExtension']] = []
|
||||
|
||||
@classmethod
|
||||
def _load_class(cls):
|
||||
super()._load_class()
|
||||
# special case @api_view: view class is nested in the cls attr of the function object
|
||||
if hasattr(cls.target_class, 'cls'):
|
||||
cls.target_class = cls.target_class.cls
|
||||
|
||||
@abstractmethod
|
||||
def view_replacement(self) -> 'Type[APIView]':
|
||||
pass # pragma: no cover
|
||||
|
||||
|
||||
class OpenApiFilterExtension(OpenApiGeneratorExtension['OpenApiFilterExtension']):
|
||||
"""
|
||||
Extension for specifying a list of filter parameters for a given ``FilterBackend``.
|
||||
|
||||
The original filter class object can be accessed via ``self.target``. The attached view
|
||||
is accessible via ``auto_schema.view``.
|
||||
|
||||
``get_schema_operation_parameters()`` is expected to return either an empty list or a list
|
||||
of valid raw `OpenAPI parameter objects
|
||||
<https://spec.openapis.org/oas/v3.0.3#parameter-object>`_.
|
||||
Using ``drf_spectacular.plumbing.build_parameter_type`` is recommended to generate
|
||||
the appropriate raw dict objects.
|
||||
"""
|
||||
_registry: List[Type['OpenApiFilterExtension']] = []
|
||||
|
||||
@abstractmethod
|
||||
def get_schema_operation_parameters(self, auto_schema: 'AutoSchema', *args, **kwargs) -> List[_SchemaType]:
|
||||
pass # pragma: no cover
|
||||
Reference in New Issue
Block a user