text: from rest_framework_jwt.authentication import JSONWebTokenAuthentication
  from rest_framework.permissions import IsAuthenticated
  from rest_framework import exceptions as rest_exceptions
  
  from django.core.exceptions import ValidationError
  
  from utils import get_error_message
  from users.models import CustomUser
  
  
  class ApiAuthMixin:
      authentication_classes = (JSONWebTokenAuthentication, )
      permission_classes = (IsAuthenticated, )
  
  
  class PublicApiMixin:
      authentication_classes = ()
      permission_classes = ()
  
  
  class ApiErrorsMixin:
      """
      Mixin that transforms Django and Python exceptions into rest_framework ones.
      Without the mixin, they return 500 status code which is not desired.
      """
      expected_exceptions = {
          ValueError: rest_exceptions.ValidationError,
          ValidationError: rest_exceptions.ValidationError,
          PermissionError: rest_exceptions.PermissionDenied,
          CustomUser.DoesNotExist: rest_exceptions.NotAuthenticated
      }
  
      def handle_exception(self, exc):
          if isinstance(exc, tuple(self.expected_exceptions.keys())):
              drf_exception_class = self.expected_exceptions[exc.__class__]
              drf_exception = drf_exception_class(get_error_message(exc))
  
              return super().handle_exception(drf_exception)
  
          return super().handle_exception(exc)