class PasswordChangeView(GenericAPIView): serializer_class = PasswordChangeSerializer permission_classes = (permissions.IsAuthenticated, ) @sensitive_post_parameters_m def dispatch(self, *args, **kwargs): return super(PasswordChangeView, self).dispatch(*args, **kwargs) @method_decorator(name='post', decorator=extend_schema( description='Set password Auth user', responses={ 200: PasswordChangeSerializer, 400: ErrorSerializer, 401: ErrorSerializer, })) def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response({ "detail": _("New password " "has been saved and e-mail " "has been sent..") })
def WithUpdatedDocstringsDecorator(cls, docstring_dict='UPDATE_DOCSTRING', kwargs_dict='KWARGS_DICT'): """Set docs on API methods ia @extend_schema.""" if not hasattr(cls, docstring_dict): raise ValueError( f"Attribute {docstring_dict} not found in class {cls}") docs = getattr(cls, docstring_dict) kwargs_dict = getattr(cls, kwargs_dict, {}) for key, value in docs.items(): if key not in kwargs_dict: kwargs_dict[key] = {} kwargs_dict[key]['description'] = value for k, v in kwargs_dict.items(): if not hasattr(cls, k): raise ValueError(f"Method {k} not found in class {cls}") old_f = getattr(cls, k) def new_fcn(*args, old_f=old_f, **kwargs): return old_f(*args, **kwargs) new_fcn.__name__ = old_f.__name__ setattr(cls, k, extend_schema(**v)(new_fcn)) return cls
def test_extend_schema_view_on_missing_view_method(capsys): @extend_schema_view(post=extend_schema(tags=['tag'])) class XAPIView(APIView): def get(self, request): pass # pragma: no cover generate_schema('x', view=XAPIView) stderr = capsys.readouterr().err assert '@extend_schema_view argument "post" was not found on view' in stderr
def view_replacement(self): @method_decorator( extend_schema(examples=self.examples, **self.extend_schema_kwargs), name=self.method, ) class Decorated(self.target_class): pass return Decorated
class UserViewSet(generics.RetrieveAPIView, generics.GenericAPIView): permission_classes = [ IsAuthenticated, ] serializer_class = UserSerializer def get_object(self): user = self.request.user self.check_object_permissions(self.request, user) return user @method_decorator(name='retrieve', decorator=extend_schema(description='Get Auth User', responses={ 200: UserSerializer, 401: ErrorSerializer, })) def get(self, request, *args, **kwargs): current_user = self.get_object() serializer = self.get_serializer(current_user) return response.Response(serializer.data) def partial_update(self, request, *args, **kwargs): current_user = self.get_object() serializer = self.get_serializer(instance=current_user, data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() if getattr(current_user, '_prefetched_objects_cache', None): current_user._prefetched_objects_cache = {} return response.Response(serializer.data) @method_decorator(name='update', decorator=extend_schema( description='Partially update Auth User', responses={ 200: UserSerializer, 400: ErrorSerializer, 401: ErrorSerializer, 404: ErrorSerializer, })) def patch(self, request, *args, **kwargs): return self.partial_update(request, *args, **kwargs)
def test_manually_set_auto_schema_with_extend_schema(no_warnings): class CustomSchema(AutoSchema): def get_override_parameters(self): if self.method.lower() == "delete": return [OpenApiParameter("custom_param", str)] return super().get_override_parameters() @extend_schema_view( list=extend_schema(summary="list summary"), destroy=extend_schema(summary="delete summary"), ) class XViewSet(mixins.ListModelMixin, mixins.DestroyModelMixin, viewsets.ViewSet): queryset = SimpleModel.objects.all() serializer_class = SimpleSerializer schema = CustomSchema() schema = generate_schema('x', XViewSet) assert schema['paths']['/x/']['get']['summary'] == 'list summary' assert schema['paths']['/x/{id}/']['delete']['summary'] == 'delete summary' assert schema['paths']['/x/{id}/']['delete']['parameters'][0]['name'] == 'custom_param' assert schema['paths']['/x/{id}/']['delete']['parameters'][1]['name'] == 'id'
def test_exclude_discovered_parameter(no_warnings): @extend_schema_view(list=extend_schema(parameters=[ # keep 'offset', remove 'limit', and add 'random' OpenApiParameter('limit', exclude=True), OpenApiParameter('random', bool), ])) class XViewset(viewsets.ReadOnlyModelViewSet): queryset = SimpleModel.objects.all() serializer_class = SimpleSerializer pagination_class = pagination.LimitOffsetPagination schema = generate_schema('x', XViewset) parameters = schema['paths']['/x/']['get']['parameters'] assert len(parameters) == 2 assert parameters[0]['name'] == 'offset' assert parameters[1]['name'] == 'random'
def test_exclude_parameter_from_customized_autoschema(no_warnings): class CustomSchema(AutoSchema): def get_override_parameters(self): return [OpenApiParameter('test')] @extend_schema_view(list=extend_schema(parameters=[ OpenApiParameter('test', exclude=True), # exclude from class override OpenApiParameter('never_existed', exclude=True), # provoke error OpenApiParameter('keep', bool), # for sanity check ])) class XViewset(viewsets.ReadOnlyModelViewSet): queryset = SimpleModel.objects.all() serializer_class = SimpleSerializer schema = CustomSchema() schema = generate_schema('x', XViewset) parameters = schema['paths']['/x/']['get']['parameters'] assert len(parameters) == 1 assert parameters[0]['name'] == 'keep'
class PasswordResetConfirmView(GenericAPIView): serializer_class = PasswordResetConfirmSerializer permission_classes = (permissions.AllowAny, ) @sensitive_post_parameters_m def dispatch(self, *args, **kwargs): return super(PasswordResetConfirmView, self).dispatch(*args, **kwargs) @method_decorator(name='post', decorator=extend_schema( description='Reset password confirm', responses={ 200: PasswordResetConfirmSerializer, 400: ErrorSerializer, })) def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response( {"detail": _("Password has been reset with the new password.")})
class PasswordResetView(GenericAPIView): serializer_class = PasswordResetSerializer permission_classes = (permissions.AllowAny, ) authentication_classes = [JWTAuthentication] @method_decorator(name='post', decorator=extend_schema(description='Reset password', responses={ 200: PasswordResetSerializer, 400: ErrorSerializer, 404: ErrorSerializer, })) def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = User.objects.filter(email=serializer.data['email']).first() if not user: raise NotFound(detail='An account with this email does not exist!') else: serializer.save() return Response({"detail": _("Password reset e-mail has been sent.")}, status=status.HTTP_200_OK)
from django.contrib.auth.models import Permission from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework.viewsets import ReadOnlyModelViewSet from hacktheback.rest.account.serializers import PermissionSerializer from hacktheback.rest.permissions import AdminSiteModelPermissions @extend_schema(tags=["Admin APIs", "Account"]) @extend_schema_view( list=extend_schema( summary="List Permissions", description="List permissions that an admin user can have.", ), retrieve=extend_schema( summary="Retrieve a Permission", description="Retrieve a permission that an admin user can have.", ), ) class PermissionAdminViewSet(ReadOnlyModelViewSet): queryset = Permission.objects.all() permission_classes = (AdminSiteModelPermissions, ) serializer_class = PermissionSerializer
class PlayoutHistoryTemplateFieldViewSet(viewsets.ModelViewSet): queryset = PlayoutHistoryTemplateField.objects.all() serializer_class = PlayoutHistoryTemplateFieldSerializer model_permission_name = "playouthistorytemplatefield" class PreferenceViewSet(viewsets.ModelViewSet): queryset = Preference.objects.all() serializer_class = PreferenceSerializer model_permission_name = "preference" @extend_schema_view(list=extend_schema(parameters=[ OpenApiParameter( name="is_valid", description="Filter on valid instances", required=False, type=bool, ), ])) class ScheduleViewSet(viewsets.ModelViewSet): queryset = Schedule.objects.all() serializer_class = ScheduleSerializer filter_fields = { "starts": FILTER_NUMERICAL_LOOKUPS, "ends": FILTER_NUMERICAL_LOOKUPS, "playout_status": FILTER_NUMERICAL_LOOKUPS, "broadcasted": FILTER_NUMERICAL_LOOKUPS, } model_permission_name = "schedule" def get_queryset(self):
def get_queryset(self): return Post.objects.order_by('-posted_at').all() def get_serializer_class(self): if self.action in ["create", "update", "partial_update", "destroy"]: return PostWriteSerializer return PostReadSerializer def perform_create(self, serializer): serializer.save(author=self.request.user) # noinspection PyMethodMayBeStatic @extend_schema_view( list=extend_schema(parameters=[ OpenApiParameter("post_pk", OpenApiTypes.UUID, OpenApiParameter.PATH) ]), retrieve=extend_schema(parameters=[ OpenApiParameter("post_pk", OpenApiTypes.UUID, OpenApiParameter.PATH) ]), create=extend_schema(parameters=[ OpenApiParameter("post_pk", OpenApiTypes.UUID, OpenApiParameter.PATH) ]), update=extend_schema(parameters=[ OpenApiParameter("post_pk", OpenApiTypes.UUID, OpenApiParameter.PATH) ]), partial_update=extend_schema(parameters=[ OpenApiParameter("post_pk", OpenApiTypes.UUID, OpenApiParameter.PATH) ]), destroy=extend_schema(parameters=[ OpenApiParameter("post_pk", OpenApiTypes.UUID, OpenApiParameter.PATH)
class PartListView(ListAPIView): """Return a list of Parts.""" serializer_class = PartSerializer pagination_class = CustomPageNumberPagination valid_query_params = ["page_size", "page", *PART_MODEL_FIELDS] def get_queryset(self): """Returns queryset filtered based on the query params.""" query_params = self._sanitise_params(self.request.GET.dict()) return Part.objects.filter(**query_params) def _sanitise_params(self, params: Dict): """Check if the params are valid. Removes pagination params.""" for key in params.keys(): if key not in self.valid_query_params: raise ValidationError("At lease one query param is invalid.") params.pop("page_size", None) params.pop("page", None) return params @extend_schema_view( retrieve=extend_schema(description="Testing the description")) class PartDetailView(RetrieveAPIView): queryset = Part.objects.all() lookup_field = "uuid" lookup_url_kwarg = "part_id" serializer_class = PartSerializer
"""Answers view set """ from django.db.models import QuerySet from drf_spectacular.utils import extend_schema_view, extend_schema from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.request import Request from rest_framework.response import Response from stackexchange import filters, models, serializers @extend_schema_view( list=extend_schema(summary='Get all answers on the site', description=' '), retrieve=extend_schema(summary='Gets the answer identified by id', description=' '), comments=extend_schema( summary='Gets the comments for an answer identified by id', description=' '), questions=extend_schema( summary='Gets the questions for an answer identified by id', description=' '), ) class AnswerViewSet(viewsets.ReadOnlyModelViewSet): """The answers view set """ filter_backends = (filters.OrderingFilter, ) def get_queryset(self) -> QuerySet: """Return the queryset for the action.
def view_replacement(self): fixed = extend_schema(responses=OpenApiTypes.FLOAT)(self.target_class) return fixed
from rest_framework.response import Response from rest_framework.serializers import BaseSerializer from .models import Robot from .serializers import ( AssetRecordSerializer, RobotCreateSerializer, RobotListSerializer, RobotRetrieveSerializer, RobotUpdateSerializer, ) @method_decorator( name="update", decorator=extend_schema(operation=None, ), ) class RobotViewSet(viewsets.ModelViewSet): serializer_class = RobotListSerializer permission_classes = [IsAdminUser] pagination_class = None action_serializer_map = { "list": RobotListSerializer, "retrieve": RobotRetrieveSerializer, "create": RobotCreateSerializer, "update": RobotUpdateSerializer, "partial_update": RobotUpdateSerializer, "partial_update_asset_record": AssetRecordSerializer, "retrieve_credential_key": CredentialKeySerializer, } resource_name = "robots"
published = filters.BooleanFilter( field_name="published", lookup_expr="exact", help_text=_("Only show lists that are published."), ) user = filters.CharFilter( field_name="created_by__username", lookup_expr="exact", help_text=_("Only show lists created by the given user."), ) @extend_schema_view( create=extend_schema( description=_("""Create a new list of tools."""), request=EditToolListSerializer, responses=ToolListSerializer, ), retrieve=extend_schema( description=_("""Details of a specific list of tools."""), responses=ToolListSerializer, ), update=extend_schema( description=_("""Update a list of tools."""), request=EditToolListSerializer, responses=ToolListSerializer, ), partial_update=extend_schema(exclude=True, ), destroy=extend_schema(description=_("""Delete a list of tools."""), ), list=extend_schema(description=_("""List all lists of tools."""), ), )
If you want to doc a default method of a Class Viewset, you have to put the method_decorator directly above of the viewset class code, and specify the name of the method that you want to doc. E.g. name='list' for the list method. If you want to doc an override Class Viewset method, or a View method, you have to place the method_decorator directly above of the desired method, without the name param """ @method_decorator(name='list', decorator=extend_schema( summary="Location list", description=read_docs_md('endpoints/core/list'), responses={ 200: LocationSerializer(many=True), 400: ErrorSerializer(), 500: ErrorSerializer() } )) class LocationViewSet(viewsets.ViewSet): """ Locations views """ def list(self, request): query = list_locations() serializer = LocationSerializer(query, many=True) return Response(serializer.data)
from argus.notificationprofile.models import DestinationConfig from argus.notificationprofile.serializers import RequestDestinationConfigSerializer from .serializers import RequestPhoneNumberSerializerV1, ResponsePhoneNumberSerializerV1, UserSerializerV1 class CurrentUserViewV1(APIView): permission_classes = [IsAuthenticated] serializer_class = UserSerializerV1 def get(self, request, *args, **kwargs): serializer = self.serializer_class(request.user) return Response(serializer.data) @extend_schema_view( create=extend_schema(request=RequestPhoneNumberSerializerV1, ), update=extend_schema(request=RequestPhoneNumberSerializerV1, ), partial_update=extend_schema(request=RequestPhoneNumberSerializerV1, ), ) class PhoneNumberViewV1(viewsets.ViewSet): permission_classes = [IsAuthenticated, IsOwner] serializer_class = ResponsePhoneNumberSerializerV1 write_serializer_class = RequestDestinationConfigSerializer queryset = DestinationConfig.objects.filter(media_id="sms").all() def list(self, request): serializer = self.serializer_class( self.queryset.filter(user=request.user), many=True) return Response(serializer.data, status=status.HTTP_200_OK) def create(self, request, pk=None):
from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import viewsets from rest_framework.exceptions import ValidationError from rest_framework.settings import api_settings from vng_api_common.viewsets import NestedViewSetMixin from objecttypes.core.constants import ObjectVersionStatus from objecttypes.core.models import ObjectType, ObjectVersion from ..filters import ObjectTypeFilterSet from ..serializers import ObjectTypeSerializer, ObjectVersionSerializer @extend_schema_view( retrieve=extend_schema(operation_id="objecttype_read"), destroy=extend_schema(operation_id="objecttype_delete"), ) class ObjectTypeViewSet(viewsets.ModelViewSet): queryset = ObjectType.objects.prefetch_related("versions").order_by("-pk") serializer_class = ObjectTypeSerializer lookup_field = "uuid" filterset_class = ObjectTypeFilterSet def perform_destroy(self, instance): if instance.versions.exists(): raise ValidationError( { api_settings.NON_FIELD_ERRORS_KEY: [ _("All related versions should be destroyed before destroying the objecttype" )
from oauth2_provider.models import AccessToken from oauth2_provider.models import Application from rest_framework import viewsets from toolhub.permissions import ObjectPermissions from toolhub.permissions import ObjectPermissionsOrAnonReadOnly from .serializers import ApplicationSerializer from .serializers import AuthorizationSerializer from .serializers import RegisterApplicationSerializer from .serializers import UpdateApplicationSerializer @extend_schema_view( list=extend_schema(description=_("""List all client applications."""), ), retrieve=extend_schema( description=_("""Info for a client application."""), ), create=extend_schema( description=_("""Register a new client application."""), responses=RegisterApplicationSerializer, request=RegisterApplicationSerializer, ), update=extend_schema(exclude=True, ), partial_update=extend_schema( description=_("""Update a client application."""), request=UpdateApplicationSerializer, ), destroy=extend_schema(description=_("""Delete a client application."""), ), ) class ApplicationViewSet(viewsets.ModelViewSet):
from rest_framework.decorators import action from rest_framework.exceptions import ParseError from rest_framework.permissions import DjangoModelPermissions, IsAuthenticated from rest_framework.response import Response from modoboa.core import models as core_models from modoboa.core import sms_backends from modoboa.lib import renderers as lib_renderers from modoboa.lib import viewsets as lib_viewsets from ... import lib, models from . import serializers @extend_schema_view( retrieve=extend_schema(description="Retrieve a particular domain", summary="Retrieve a particular domain"), list=extend_schema(description="Retrieve a list of domains", summary="Retrieve a list of domains"), create=extend_schema(description="Create a new domain", summary="Create a new domain")) class DomainViewSet(lib_viewsets.RevisionModelMixin, viewsets.ModelViewSet): """Domain viewset.""" permission_classes = [ IsAuthenticated, DjangoModelPermissions, ] serializer_class = serializers.DomainSerializer def get_queryset(self): """Filter queryset based on current user."""
"prefix": prefix.prefix, "vrf": prefix.vrf, }, ) return Response(serializer.data) # # IP addresses # @extend_schema_view( bulk_update=extend_schema( responses={"200": serializers.IPAddressSerializerLegacy(many=True)}, versions=["1.2"]), bulk_partial_update=extend_schema( responses={"200": serializers.IPAddressSerializerLegacy(many=True)}, versions=["1.2"]), create=extend_schema( responses={"201": serializers.IPAddressSerializerLegacy}, versions=["1.2"]), list=extend_schema( responses={"200": serializers.IPAddressSerializerLegacy(many=True)}, versions=["1.2"]), partial_update=extend_schema( responses={"200": serializers.IPAddressSerializerLegacy}, versions=["1.2"]), retrieve=extend_schema( responses={"200": serializers.IPAddressSerializerLegacy},
@extend_schema_view(list=extend_schema(parameters=[ OpenApiParameter( name="acked", description="Fetch acked (`true`) or unacked (`false`) incidents.", enum=BooleanStringOAEnum, ), OpenApiParameter( name="cursor", description="The pagination cursor value.", type=str), OpenApiParameter( name="end_time__gte", description="Fetch incidents that ended on or after `END_TIME`", type=OpenApiTypes.DATETIME, ), OpenApiParameter( name="end_time__isnull", description= 'Fetch incidents that have `end_time` set to None (`true`), a datetime or "infinity" (`false`).', enum=BooleanStringOAEnum, ), OpenApiParameter( name="end_time__lte", description="Fetch incidents that ended on or before `END_TIME`", type=OpenApiTypes.DATETIME, ), OpenApiParameter(name="level__lte", description="Fetch incidents with levels in `LEVEL`", enum=Incident.LEVELS), OpenApiParameter( name="open", description="Fetch open (`true`) or closed (`false`) incidents.", enum=BooleanStringOAEnum, ), OpenApiParameter( name="source__id__in", description= "Fetch incidents with a source with numeric id `ID1` or `ID2` or..", ), OpenApiParameter( name="source_incident_id", description="Fetch incidents with the specific source incident id.", ), OpenApiParameter( name="source__name__in", description= "Fetch incidents with a source with name ``NAME1`` or ``NAME2`` or..", ), OpenApiParameter( name="source__type__in", description= "Fetch incidents with a source of a type with numeric id `ID1` or `ID2` or..", ), OpenApiParameter( name="start_time__gte", description="Fetch incidents that started on or after `START_TIME`", type=OpenApiTypes.DATETIME, ), OpenApiParameter( name="start_time__lte", description="Fetch incidents that started on or before `START_TIME`", type=OpenApiTypes.DATETIME, ), OpenApiParameter( name="stateful", description="Fetch stateful (`true`) or stateless (`false`) incidents.", enum=BooleanStringOAEnum, ), ]))
from drf_spectacular.utils import extend_schema_view, extend_schema from rest_framework import viewsets from stackexchange import filters, models, serializers @extend_schema_view( list=extend_schema(summary='Get all comments on the site'), retrieve=extend_schema(summary='Gets the comment identified by id'), ) class CommentViewSet(viewsets.ReadOnlyModelViewSet): """The answers view set """ queryset = models.Comment.objects.select_related('post', 'user') serializer_class = serializers.CommentSerializer filter_backends = (filters.OrderingFilter, ) @staticmethod def get_ordering_fields(): """Return the ordering fields for the action. :return: The ordering fields for the action. """ return ('creation', 'desc', 'creation_date'), ('votes', 'desc', 'score')
from django.db.models import QuerySet from drf_spectacular.utils import extend_schema from rest_framework import status from rest_framework.viewsets import ModelViewSet from common.models import Example from common.serializers import ExampleSerializer from common.utils import create_swagger_info @create_swagger_info( extend_schema( operation_id="Operation id", description="Example description", summary="Example operation summary", auth=[], request=ExampleSerializer(), responses={status.HTTP_201_CREATED: ExampleSerializer()}, tags=["Common"], ) ) class ExampleViewSet(ModelViewSet): serializer_class = ExampleSerializer queryset: QuerySet[Example] = Example.published.all()
"""The users view set. """ from django.db.models import QuerySet from drf_spectacular.utils import extend_schema_view, extend_schema from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.request import Request from rest_framework.response import Response from stackexchange import filters, models, serializers @extend_schema_view( list=extend_schema(summary='Get all users on the site', description=' '), retrieve=extend_schema(summary='Gets the user identified by id', description=' '), answers=extend_schema(summary='Get the answers posted by the user identified by id', description=' '), badges=extend_schema(summary='Get the badges earned by the user identified by id', description=' '), comments=extend_schema(summary='Get the comments posted by the user identified by id', description=' '), posts=extend_schema(summary='Get all posts (questions and answers) owned by a user', description=' '), questions=extend_schema(summary='Get the questions posted by the user identified by id', description=' '), ) class UserViewSet(viewsets.ReadOnlyModelViewSet): """The user view set """ filter_backends = (filters.OrderingFilter, ) def get_queryset(self) -> QuerySet: """Return the queryset for the action. :return: The queryset for the action """
from objects.token.models import Permission from objects.token.permissions import ObjectTypeBasedPermission from ..kanalen import KANAAL_OBJECTEN from ..mixins import GeoMixin, ObjectNotificationMixin from ..serializers import ( HistoryRecordSerializer, ObjectSearchSerializer, ObjectSerializer, ) from .filters import ObjectRecordFilterSet @extend_schema_view( list=extend_schema( description="Retrieve a list of OBJECTs and their actual RECORD. " "The actual record is defined as if the query parameter `date=<today>` was given." ), retrieve=extend_schema( description="Retrieve a single OBJECT and its actual RECORD. " "The actual record is defined as if the query parameter `date=<today>` was given.", operation_id="object_read", ), create=extend_schema( description="Create an OBJECT and its initial RECORD."), update=extend_schema( description= "Update the OBJECT by creating a new RECORD with the updates values."), partial_update=extend_schema( description= "Update the OBJECT by creating a new RECORD with the updates values."), destroy=extend_schema(
from drf_spectacular.utils import extend_schema_view, extend_schema from rest_framework.authtoken.views import ObtainAuthToken from rest_framework.authtoken.models import Token from rest_framework.response import Response from shopping_mate.apps.authentication.response import HttpBasic401 @extend_schema_view( post=extend_schema( summary='User login', description='Allows users to login.', ), ) class CustomAuthToken(ObtainAuthToken): def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) if not serializer.is_valid(): return HttpBasic401() user = serializer.validated_data['user'] Token.objects.filter(user=user).delete() token, created = Token.objects.get_or_create(user=user) return Response({ 'token': token.key, 'user_id': user.pk, 'username': user.email })