packed

packed is a Python library that provides a simple way to serialize (pack) and deserialize (unpack) custom Python objects, leveraging the efficient MessagePack binary serialization format. It's designed to help you easily transmit objects over networks, save them to files, or perform any operation that requires converting objects to bytes and back.
Features
- Efficient Binary Serialization: Uses MessagePack, an efficient binary serialization format that's faster and smaller than JSON.
- Simple Decorator-Based Registration: Easily register your custom classes for packing and unpacking using the
@packable decorator.
- Customizable Serialization: Define exactly what data gets serialized by implementing the
__packed__ method.
- Supports Custom Unpacking Logic: Use the
__unpacked__ class method to control how objects are reconstructed during unpacking.
- Seamless Integration: Works with standard Python types and custom objects, making it easy to integrate into existing projects.
Installation
Install packed using pip:
pip3 install packed
Quick Start
Making a Class Packable
To make a custom class packable, decorate it with @packable and define a __packed__ method that returns a dictionary of the attributes you want to serialize.
from packed import packable
@packable
class EqualMatcher:
def __init__(self, expected):
self._expected = expected
def match(self, actual):
return actual == self._expected
def __packed__(self):
return {"expected": self._expected}
Packing Objects
Use the pack function to serialize an object into bytes.
Client Side:
from packed import pack
matcher = EqualMatcher("banana")
packed_data = pack(matcher)
Unpacking Objects
Use the unpack function to deserialize bytes back into an object.
Server Side:
from packed import unpack
matcher = unpack(packed_data)
assert matcher.match("banana") is True
Supported Data Types
packed supports serialization of the following standard Python data types:
- Primitive Types:
int, float, bool, None, str, bytes
- Collections:
- Lists:
[1, 2, 3]
- Tuples:
(1, 2, 3)
- Dictionaries:
{'key': 'value'}
- Sets:
{1, 2, 3}
- Nested Structures: Collections containing other collections or primitive types.
- Custom Objects: Classes registered with the
@packable decorator.
These types are serialized using MessagePack's built-in support for these data types, ensuring efficient and reliable serialization.
How It Works
Advanced Usage
Custom Unpacking Logic
If your class requires custom logic during unpacking, define a __unpacked__ class method.
@packable
class MyClass:
def __init__(self, value):
self.value = value
def __packed__(self):
return {'value': self.value}
@classmethod
def __unpacked__(cls, value):
instance = cls(value)
instance.setup_additional_state()
return instance
def setup_additional_state(self):
pass
Registering Classes with Custom Names
You can register a class with a custom name by passing the name to the decorator. This is useful if you need to avoid name collisions or want to use a different identifier.
@packable("CustomName")
class MyClass:
Handling Subclasses
If you have a class hierarchy, register each subclass separately if you intend to pack and unpack them.
@packable
class BaseClass:
@packable
class SubClass(BaseClass):
MessagePack
MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller.
By using MessagePack under the hood, packed provides:
- Efficiency: Smaller message sizes and faster serialization/deserialization compared to text-based formats like JSON.
- Interoperability: Support for multiple languages, making it easier to integrate with systems written in different programming languages.
- Simplicity: A straightforward and easy-to-use API.
packed uses umsgpack, a pure Python implementation of MessagePack, for serialization and deserialization. This ensures that the library is lightweight and has minimal dependencies, making it easy to install and integrate.