Source code for dmr.options_mixins

from http import HTTPStatus
from typing import TYPE_CHECKING, Final

from django.http import HttpResponse

from dmr.endpoint import validate
from dmr.headers import HeaderSpec
from dmr.metadata import ResponseSpec

if TYPE_CHECKING:
    from dmr.controller import Controller
    from dmr.serializer import BaseSerializer


#: Metadata for the default options response.
OptionsResponse: Final = ResponseSpec(
    None,
    status_code=HTTPStatus.NO_CONTENT,
    headers={'Allow': HeaderSpec()},
)


[docs] class MetaMixin: """ Mixin that provides default ``meta`` method or ``OPTIONS`` http method. Use it for sync controllers. It just returns the list of allowed methods. Use it as a mixin with the :class:`dmr.controller.Controller` type: .. code:: python >>> from dmr import Controller >>> from dmr.options_mixins import MetaMixin >>> from dmr.plugins.pydantic import PydanticSerializer >>> class SupportsOptionsHttpMethod( ... MetaMixin, ... Controller[PydanticSerializer], ... ): ... """ __slots__ = ()
[docs] @validate(OptionsResponse) def meta(self) -> HttpResponse: """Default sync implementation for ``OPTIONS`` http method.""" return _meta_impl(self) # type: ignore[arg-type]
[docs] class AsyncMetaMixin: """ Mixin that provides default ``meta`` method or ``OPTIONS`` http method. Use it for async controllers. It just returns the list of allowed methods. Use it as a mixin with the :class:`dmr.controller.Controller` type: .. code:: python >>> from dmr import Controller >>> from dmr.options_mixins import AsyncMetaMixin >>> from dmr.plugins.pydantic import PydanticSerializer >>> class SupportsOptionsHttpMethod( ... AsyncMetaMixin, ... Controller[PydanticSerializer], ... ): ... """ __slots__ = ()
[docs] @validate(OptionsResponse) async def meta(self) -> HttpResponse: """Default async implementation for ``OPTIONS`` http method.""" return _meta_impl(self) # type: ignore[arg-type]
def _meta_impl(controller: 'Controller[BaseSerializer]') -> HttpResponse: allow = ', '.join( method for method in sorted(controller.api_endpoints.keys()) ) return controller.to_response( raw_data=None, status_code=HTTPStatus.NO_CONTENT, headers={'Allow': allow}, )