Coverage for ion/core/messaging/serialization : 59.72%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
|
""" Centralized support for encoding/decoding of data structures. Requires a json library (`cjson`_, `simplejson`_, or `Python 2.6+`_).
Optionally installs support for ``YAML`` if the necessary PyYAML is installed.
.. _`cjson`: http://pypi.python.org/pypi/python-cjson/ .. _`simplejson`: http://code.google.com/p/simplejson/ .. _`Python 2.6+`: http://docs.python.org/library/json.html .. _`PyYAML`: http://pyyaml.org/
"""
"""Support for the requested serialization type is not installed"""
"""The registry keeps track of serialization methods."""
content_encoding='utf-8'): """Register a new encoder/decoder.
:param name: A convenience name for the serialization method.
:param encoder: A method that will be passed a python data structure and should return a string representing the serialized data. If ``None``, then only a decoder will be registered. Encoding will not be possible.
:param decoder: A method that will be passed a string representing serialized data and should return a python data structure. If ``None``, then only an encoder will be registered. Decoding will not be possible.
:param content_type: The mime-type describing the serialized structure.
:param content_encoding: The content encoding (character set) that the :param:`decoder` method will be returning. Will usually be ``utf-8``, ``us-ascii``, or ``binary``.
"""
""" Set the default serialization method used by this library.
:param name: The name of the registered serialization method. For example, ``json`` (default), ``pickle``, ``yaml``, or any custom methods registered using :meth:`register`.
:raises SerializerNotInstalled: If the serialization method requested is not available. """ self._default_encode) = self._encoders[name] except KeyError: raise SerializerNotInstalled( "No encoder installed for %s" % name)
""" Serialize a data structure into a string suitable for sending as an AMQP message body.
:param data: The message data to send. Can be a list, dictionary or a string.
:keyword serializer: An optional string representing the serialization method you want the data marshalled into. (For example, ``json``, ``raw``, or ``pickle``).
If ``None`` (default), then `JSON`_ will be used, unless ``data`` is a ``str`` or ``unicode`` object. In this latter case, no serialization occurs as it would be unnecessary.
Note that if ``serializer`` is specified, then that serialization method will be used even if a ``str`` or ``unicode`` object is passed in.
:returns: A three-item tuple containing the content type (e.g., ``application/json``), content encoding, (e.g., ``utf-8``) and a string containing the serialized data.
:raises SerializerNotInstalled: If the serialization method requested is not available. """ return raw_encode(data) raise SerializerNotInstalled( "No encoder installed for %s" % serializer)
# If a raw string was sent, assume binary encoding # (it's likely either ASCII or a raw binary file, but 'binary' # charset will encompass both, even if not ideal. # In Python 3+, this would be "bytes"; allow binary data to be # sent as a message without getting encoder errors return "application/data", "binary", data
# For unicode objects, force it into a string payload = data.encode("utf-8") return "text/plain", "utf-8", payload
content_type, content_encoding, encoder = \ self._encoders[serializer] else:
"""Deserialize a data stream as serialized using ``encode`` based on :param:`content_type`.
:param data: The message data to deserialize.
:param content_type: The content-type of the data. (e.g., ``application/json``).
:param content_encoding: The content-encoding of the data. (e.g., ``utf-8``, ``binary``, or ``us-ascii``).
:returns: The unserialized data. """
# Don't decode 8-bit strings or unicode objects not isinstance(data, unicode): data = codecs.decode(data, content_encoding)
except KeyError: return data
""" .. data:: registry
Global registry of serializers/deserializers.
"""
""" .. function:: encode(data, serializer=default_serializer)
Encode data using the registry's default encoder.
"""
""" .. function:: decode(data, content_type, content_encoding):
Decode data using the registry's default decoder.
"""
"""Special case serializer.""" content_type = 'application/data' payload = data if isinstance(payload, unicode): content_encoding = 'utf-8' payload = payload.encode(content_encoding) else: content_encoding = 'binary' return content_type, content_encoding, payload
"""Register a encoder/decoder for JSON serialization.""" #from anyjson import serialize as json_serialize #from anyjson import deserialize as json_deserialize from simplejson import dumps, loads
registry.register('json', dumps, loads, content_type='application/json', content_encoding='utf-8')
"""Register a encoder/decoder for YAML serialization.
It is slower than JSON, but allows for more data types to be serialized. Useful if you need to send data such as dates""" try: import yaml registry.register('yaml', yaml.safe_dump, yaml.safe_load, content_type='application/x-yaml', content_encoding='utf-8') except ImportError:
def not_available(*args, **kwargs): """In case a client receives a yaml message, but yaml isn't installed.""" raise SerializerNotInstalled( "No decoder installed for YAML. Install the PyYAML library") registry.register('yaml', None, not_available, 'application/x-yaml')
"""The fastest serialization method, but restricts you to python clients.""" import cPickle registry.register('pickle', cPickle.dumps, cPickle.loads, content_type='application/x-python-serialize', content_encoding='binary')
# Register the base serialization methods. #register_json() #register_pickle() #register_yaml()
# JSON is assumed to always be available, so is the default. # (this matches the historical use of carrot.) #registry._set_default_serializer('json') |