Source code for falcon.media.msgpack
from __future__ import absolute_import # NOTE(kgriffs): Work around a Cython bug
from typing import Union
from falcon import errors
from falcon.media.base import BaseHandler
from falcon.media.base import BinaryBaseHandlerWS
[docs]class MessagePackHandler(BaseHandler):
"""Handler built using the :py:mod:`msgpack` module.
This handler uses ``msgpack.unpackb()`` and ``msgpack.Packer().pack()``. The
MessagePack ``bin`` type is used to distinguish between Unicode strings
(of type ``str``) and byte strings (of type ``bytes``).
This handler will raise a :class:`falcon.MediaNotFoundError` when attempting
to parse an empty body; it will raise a :class:`falcon.MediaMalformedError`
if an error happens while parsing the body.
Note:
This handler requires the extra ``msgpack`` package (version 0.5.2
or higher), which must be installed in addition to ``falcon`` from
PyPI:
.. code::
$ pip install msgpack
"""
def __init__(self):
import msgpack
packer = msgpack.Packer(autoreset=True, use_bin_type=True)
self._pack = packer.pack
self._unpackb = msgpack.unpackb
# NOTE(kgriffs): To be safe, only enable the optimized protocol when
# not subclassed.
if type(self) is MessagePackHandler:
self._serialize_sync = self._pack
self._deserialize_sync = self._deserialize
def _deserialize(self, data):
if not data:
raise errors.MediaNotFoundError('MessagePack')
try:
# NOTE(jmvrbanac): Using unpackb since we would need to manage
# a buffer for Unpacker() which wouldn't gain us much.
return self._unpackb(data, raw=False)
except ValueError as err:
raise errors.MediaMalformedError('MessagePack') from err
def deserialize(self, stream, content_type, content_length):
return self._deserialize(stream.read())
async def deserialize_async(self, stream, content_type, content_length):
return self._deserialize(await stream.read())
def serialize(self, media, content_type) -> bytes:
return self._pack(media)
async def serialize_async(self, media, content_type) -> bytes:
return self._pack(media)
[docs]class MessagePackHandlerWS(BinaryBaseHandlerWS):
"""WebSocket media handler for de(serializing) MessagePack to/from BINARY payloads.
This handler uses ``msgpack.unpackb()`` and ``msgpack.packb()``. The
MessagePack ``bin`` type is used to distinguish between Unicode strings
(of type ``str``) and byte strings (of type ``bytes``).
Note:
This handler requires the extra ``msgpack`` package (version 0.5.2
or higher), which must be installed in addition to ``falcon`` from
PyPI:
.. code::
$ pip install msgpack
"""
__slots__ = ['msgpack', 'packer']
def __init__(self):
import msgpack
packer = msgpack.Packer(autoreset=True, use_bin_type=True)
self._pack = packer.pack
self._unpackb = msgpack.unpackb
def serialize(self, media: object) -> Union[bytes, bytearray, memoryview]:
return self._pack(media)
def deserialize(self, payload: bytes) -> object:
# NOTE(jmvrbanac): Using unpackb since we would need to manage
# a buffer for Unpacker() which wouldn't gain us much.
return self._unpackb(payload, raw=False)