diff --git a/django_etebase/drf_msgpack/__init__.py b/django_etebase/drf_msgpack/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django_etebase/drf_msgpack/apps.py b/django_etebase/drf_msgpack/apps.py new file mode 100644 index 0000000..619e3e0 --- /dev/null +++ b/django_etebase/drf_msgpack/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class DrfMsgpackConfig(AppConfig): + name = 'drf_msgpack' diff --git a/django_etebase/drf_msgpack/migrations/__init__.py b/django_etebase/drf_msgpack/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django_etebase/drf_msgpack/parsers.py b/django_etebase/drf_msgpack/parsers.py new file mode 100644 index 0000000..44cd33b --- /dev/null +++ b/django_etebase/drf_msgpack/parsers.py @@ -0,0 +1,14 @@ +import msgpack + +from rest_framework.parsers import BaseParser +from rest_framework.exceptions import ParseError + + +class MessagePackParser(BaseParser): + media_type = 'application/msgpack' + + def parse(self, stream, media_type=None, parser_context=None): + try: + return msgpack.unpackb(stream.read(), raw=False) + except Exception as exc: + raise ParseError('MessagePack parse error - %s' % str(exc)) diff --git a/django_etebase/drf_msgpack/renderers.py b/django_etebase/drf_msgpack/renderers.py new file mode 100644 index 0000000..9445231 --- /dev/null +++ b/django_etebase/drf_msgpack/renderers.py @@ -0,0 +1,15 @@ +import msgpack + +from rest_framework.renderers import BaseRenderer + + +class MessagePackRenderer(BaseRenderer): + media_type = 'application/msgpack' + format = 'msgpack' + render_style = 'binary' + charset = None + + def render(self, data, media_type=None, renderer_context=None): + if data is None: + return b'' + return msgpack.packb(data, use_bin_type=True) diff --git a/django_etebase/drf_msgpack/views.py b/django_etebase/drf_msgpack/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/django_etebase/drf_msgpack/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/django_etebase/views.py b/django_etebase/views.py index c7fdab5..93a7645 100644 --- a/django_etebase/views.py +++ b/django_etebase/views.py @@ -26,9 +26,10 @@ from django.shortcuts import get_object_or_404 from rest_framework import status from rest_framework import viewsets -from rest_framework import parsers from rest_framework.decorators import action as action_decorator from rest_framework.response import Response +from rest_framework.parsers import JSONParser, FormParser, MultiPartParser +from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer import nacl.encoding import nacl.signing @@ -37,6 +38,9 @@ import nacl.hash from .token_auth.models import AuthToken +from .drf_msgpack.parsers import MessagePackParser +from .drf_msgpack.renderers import MessagePackRenderer + from . import app_settings, permissions from .models import ( Collection, @@ -83,6 +87,8 @@ def msgpack_decode(content): class BaseViewSet(viewsets.ModelViewSet): authentication_classes = tuple(app_settings.API_AUTHENTICATORS) permission_classes = tuple(app_settings.API_PERMISSIONS) + renderer_classes = [JSONRenderer, MessagePackRenderer, BrowsableAPIRenderer] + parser_classes = [JSONParser, MessagePackParser, FormParser, MultiPartParser] stoken_id_fields = None def get_serializer_class(self): @@ -398,9 +404,10 @@ class CollectionItemViewSet(BaseViewSet): class CollectionItemChunkViewSet(viewsets.ViewSet): allowed_methods = ['GET', 'POST'] - parser_classes = (parsers.MultiPartParser, ) authentication_classes = BaseViewSet.authentication_classes permission_classes = BaseViewSet.permission_classes + renderer_classes = BaseViewSet.renderer_classes + parser_classes = (MultiPartParser, ) serializer_class = CollectionItemChunkSerializer lookup_field = 'uid' @@ -602,6 +609,8 @@ class InvitationIncomingViewSet(InvitationBaseViewSet): class AuthenticationViewSet(viewsets.ViewSet): allowed_methods = ['POST'] authentication_classes = BaseViewSet.authentication_classes + renderer_classes = BaseViewSet.renderer_classes + parser_classes = BaseViewSet.parser_classes def get_encryption_key(self, salt): key = nacl.hash.blake2b(settings.SECRET_KEY.encode(), encoder=nacl.encoding.RawEncoder) @@ -757,6 +766,8 @@ class AuthenticationViewSet(viewsets.ViewSet): class TestAuthenticationViewSet(viewsets.ViewSet): allowed_methods = ['POST'] + renderer_classes = BaseViewSet.renderer_classes + parser_classes = BaseViewSet.parser_classes def list(self, request): return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)