drf_msgpack: add code to parse/serialise msgpack

It's not actually used by clients but it's there and can be used. It
works for receiving msgpack messages, but doesn't yet work for sending
because some of the types will be converted to base64.
master
Tom Hacohen 4 years ago
parent fbf5552a62
commit 2880673e27

@ -0,0 +1,5 @@
from django.apps import AppConfig
class DrfMsgpackConfig(AppConfig):
name = 'drf_msgpack'

@ -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))

@ -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)

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

@ -26,9 +26,10 @@ from django.shortcuts import get_object_or_404
from rest_framework import status from rest_framework import status
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework import parsers
from rest_framework.decorators import action as action_decorator from rest_framework.decorators import action as action_decorator
from rest_framework.response import Response 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.encoding
import nacl.signing import nacl.signing
@ -37,6 +38,9 @@ import nacl.hash
from .token_auth.models import AuthToken from .token_auth.models import AuthToken
from .drf_msgpack.parsers import MessagePackParser
from .drf_msgpack.renderers import MessagePackRenderer
from . import app_settings, permissions from . import app_settings, permissions
from .models import ( from .models import (
Collection, Collection,
@ -83,6 +87,8 @@ def msgpack_decode(content):
class BaseViewSet(viewsets.ModelViewSet): class BaseViewSet(viewsets.ModelViewSet):
authentication_classes = tuple(app_settings.API_AUTHENTICATORS) authentication_classes = tuple(app_settings.API_AUTHENTICATORS)
permission_classes = tuple(app_settings.API_PERMISSIONS) permission_classes = tuple(app_settings.API_PERMISSIONS)
renderer_classes = [JSONRenderer, MessagePackRenderer, BrowsableAPIRenderer]
parser_classes = [JSONParser, MessagePackParser, FormParser, MultiPartParser]
stoken_id_fields = None stoken_id_fields = None
def get_serializer_class(self): def get_serializer_class(self):
@ -398,9 +404,10 @@ class CollectionItemViewSet(BaseViewSet):
class CollectionItemChunkViewSet(viewsets.ViewSet): class CollectionItemChunkViewSet(viewsets.ViewSet):
allowed_methods = ['GET', 'POST'] allowed_methods = ['GET', 'POST']
parser_classes = (parsers.MultiPartParser, )
authentication_classes = BaseViewSet.authentication_classes authentication_classes = BaseViewSet.authentication_classes
permission_classes = BaseViewSet.permission_classes permission_classes = BaseViewSet.permission_classes
renderer_classes = BaseViewSet.renderer_classes
parser_classes = (MultiPartParser, )
serializer_class = CollectionItemChunkSerializer serializer_class = CollectionItemChunkSerializer
lookup_field = 'uid' lookup_field = 'uid'
@ -602,6 +609,8 @@ class InvitationIncomingViewSet(InvitationBaseViewSet):
class AuthenticationViewSet(viewsets.ViewSet): class AuthenticationViewSet(viewsets.ViewSet):
allowed_methods = ['POST'] allowed_methods = ['POST']
authentication_classes = BaseViewSet.authentication_classes authentication_classes = BaseViewSet.authentication_classes
renderer_classes = BaseViewSet.renderer_classes
parser_classes = BaseViewSet.parser_classes
def get_encryption_key(self, salt): def get_encryption_key(self, salt):
key = nacl.hash.blake2b(settings.SECRET_KEY.encode(), encoder=nacl.encoding.RawEncoder) key = nacl.hash.blake2b(settings.SECRET_KEY.encode(), encoder=nacl.encoding.RawEncoder)
@ -757,6 +766,8 @@ class AuthenticationViewSet(viewsets.ViewSet):
class TestAuthenticationViewSet(viewsets.ViewSet): class TestAuthenticationViewSet(viewsets.ViewSet):
allowed_methods = ['POST'] allowed_methods = ['POST']
renderer_classes = BaseViewSet.renderer_classes
parser_classes = BaseViewSet.parser_classes
def list(self, request): def list(self, request):
return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

Loading…
Cancel
Save