# packed
[![Codecov](https://img.shields.io/codecov/c/github/tsv1/packed/master.svg?style=flat-square)](https://codecov.io/gh/tsv1/packed)
[![PyPI](https://img.shields.io/pypi/v/packed.svg?style=flat-square)](https://pypi.python.org/pypi/packed/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/packed?style=flat-square)](https://pypi.python.org/pypi/packed/)
[![Python Version](https://img.shields.io/pypi/pyversions/packed.svg?style=flat-square)](https://pypi.python.org/pypi/packed/)
**packed** is a Python library that provides a simple way to serialize (pack) and deserialize (unpack) custom Python objects, leveraging the efficient [MessagePack](https://msgpack.org/) 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](https://msgpack.org/), 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](https://pypi.python.org/pypi/packed/) using `pip`:
```sh
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.
```python
from packed import packable
@packable # Register the class for packing
class EqualMatcher:
def __init__(self, expected):
self._expected = expected
def match(self, actual):
return actual == self._expected
def __packed__(self): # Select the fields to pack
return {"expected": self._expected}
```
### Packing Objects
Use the `pack` function to serialize an object into bytes.
**Client Side:**
```python
from packed import pack
matcher = EqualMatcher("banana")
packed_data = pack(matcher)
# You can now send 'packed_data' over a network or save it to a file
```
### Unpacking Objects
Use the `unpack` function to deserialize bytes back into an object.
**Server Side:**
```python
from packed import unpack
# Assume 'packed_data' is received from a network or read from a file
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
1. **Registration**: When you decorate a class with `@packable`, it gets registered with the internal resolver. This allows the `packed` library to keep track of which classes can be packed and unpacked.
2. **Packing**:
- The `__packed__` method you define in your class specifies what data gets serialized.
- The `pack` function uses this method to convert your object into a serializable form.
- Metadata about the object's class is included to ensure it can be properly reconstructed.
3. **Unpacking**:
- The `unpack` function reads the metadata and reconstructs the object.
- If your class defines a `__unpacked__` class method, it will use that to create the object.
- Otherwise, it will call the class constructor with the unpacked data.
## Advanced Usage
### Custom Unpacking Logic
If your class requires custom logic during unpacking, define a `__unpacked__` class method.
```python
@packable
class MyClass:
def __init__(self, value):
self.value = value
def __packed__(self):
return {'value': self.value}
@classmethod
def __unpacked__(cls, value):
# Custom logic during unpacking
instance = cls(value)
instance.setup_additional_state()
return instance
def setup_additional_state(self):
# Additional initialization
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.
```python
@packable("CustomName")
class MyClass:
# Class definition
```
### Handling Subclasses
If you have a class hierarchy, register each subclass separately if you intend to pack and unpack them.
```python
@packable
class BaseClass:
# Base class definition
@packable
class SubClass(BaseClass):
# Subclass definition
```
## MessagePack
[MessagePack](https://msgpack.org/) 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](https://github.com/vsergeev/u-msgpack-python), 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.
Raw data
{
"_id": null,
"home_page": "https://github.com/tsv1/packed",
"name": "packed",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": null,
"author": "Nikita Tsvetkov",
"author_email": "tsv1@fastmail.com",
"download_url": "https://files.pythonhosted.org/packages/2d/38/f702609d61a50a103715b4a80cc8fbaf7c528f68f80c86adf353f45848a2/packed-0.3.0.tar.gz",
"platform": null,
"description": "# packed\n\n[![Codecov](https://img.shields.io/codecov/c/github/tsv1/packed/master.svg?style=flat-square)](https://codecov.io/gh/tsv1/packed)\n[![PyPI](https://img.shields.io/pypi/v/packed.svg?style=flat-square)](https://pypi.python.org/pypi/packed/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/packed?style=flat-square)](https://pypi.python.org/pypi/packed/)\n[![Python Version](https://img.shields.io/pypi/pyversions/packed.svg?style=flat-square)](https://pypi.python.org/pypi/packed/)\n\n**packed** is a Python library that provides a simple way to serialize (pack) and deserialize (unpack) custom Python objects, leveraging the efficient [MessagePack](https://msgpack.org/) 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.\n\n## Features\n\n- **Efficient Binary Serialization**: Uses [MessagePack](https://msgpack.org/), an efficient binary serialization format that's faster and smaller than JSON.\n- **Simple Decorator-Based Registration**: Easily register your custom classes for packing and unpacking using the `@packable` decorator.\n- **Customizable Serialization**: Define exactly what data gets serialized by implementing the `__packed__` method.\n- **Supports Custom Unpacking Logic**: Use the `__unpacked__` class method to control how objects are reconstructed during unpacking.\n- **Seamless Integration**: Works with standard Python types and custom objects, making it easy to integrate into existing projects.\n\n## Installation\n\nInstall [packed](https://pypi.python.org/pypi/packed/) using `pip`:\n\n```sh\npip3 install packed\n```\n\n## Quick Start\n\n### Making a Class Packable\n\nTo 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.\n\n```python\nfrom packed import packable\n\n@packable # Register the class for packing\nclass EqualMatcher:\n def __init__(self, expected):\n self._expected = expected\n\n def match(self, actual):\n return actual == self._expected\n\n def __packed__(self): # Select the fields to pack\n return {\"expected\": self._expected}\n```\n\n### Packing Objects\n\nUse the `pack` function to serialize an object into bytes.\n\n**Client Side:**\n\n```python\nfrom packed import pack\n\nmatcher = EqualMatcher(\"banana\")\npacked_data = pack(matcher)\n# You can now send 'packed_data' over a network or save it to a file\n```\n\n### Unpacking Objects\n\nUse the `unpack` function to deserialize bytes back into an object.\n\n**Server Side:**\n\n```python\nfrom packed import unpack\n\n# Assume 'packed_data' is received from a network or read from a file\nmatcher = unpack(packed_data)\nassert matcher.match(\"banana\") is True\n```\n\n## Supported Data Types\n\n**packed** supports serialization of the following standard Python data types:\n\n- **Primitive Types**: `int`, `float`, `bool`, `None`, `str`, `bytes`\n- **Collections**:\n - **Lists**: `[1, 2, 3]`\n - **Tuples**: `(1, 2, 3)`\n - **Dictionaries**: `{'key': 'value'}`\n - **Sets**: `{1, 2, 3}`\n- **Nested Structures**: Collections containing other collections or primitive types.\n- **Custom Objects**: Classes registered with the `@packable` decorator.\n\nThese types are serialized using MessagePack's built-in support for these data types, ensuring efficient and reliable serialization.\n\n## How It Works\n\n1. **Registration**: When you decorate a class with `@packable`, it gets registered with the internal resolver. This allows the `packed` library to keep track of which classes can be packed and unpacked.\n\n2. **Packing**:\n - The `__packed__` method you define in your class specifies what data gets serialized.\n - The `pack` function uses this method to convert your object into a serializable form.\n - Metadata about the object's class is included to ensure it can be properly reconstructed.\n\n3. **Unpacking**:\n - The `unpack` function reads the metadata and reconstructs the object.\n - If your class defines a `__unpacked__` class method, it will use that to create the object.\n - Otherwise, it will call the class constructor with the unpacked data.\n\n## Advanced Usage\n\n### Custom Unpacking Logic\n\nIf your class requires custom logic during unpacking, define a `__unpacked__` class method.\n\n```python\n@packable\nclass MyClass:\n def __init__(self, value):\n self.value = value\n\n def __packed__(self):\n return {'value': self.value}\n\n @classmethod\n def __unpacked__(cls, value):\n # Custom logic during unpacking\n instance = cls(value)\n instance.setup_additional_state()\n return instance\n\n def setup_additional_state(self):\n # Additional initialization\n pass\n```\n\n### Registering Classes with Custom Names\n\nYou 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.\n\n```python\n@packable(\"CustomName\")\nclass MyClass:\n # Class definition\n```\n\n### Handling Subclasses\n\nIf you have a class hierarchy, register each subclass separately if you intend to pack and unpack them.\n\n```python\n@packable\nclass BaseClass:\n # Base class definition\n\n@packable\nclass SubClass(BaseClass):\n # Subclass definition\n```\n\n## MessagePack\n\n[MessagePack](https://msgpack.org/) is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller.\n\nBy using MessagePack under the hood, **packed** provides:\n\n- **Efficiency**: Smaller message sizes and faster serialization/deserialization compared to text-based formats like JSON.\n- **Interoperability**: Support for multiple languages, making it easier to integrate with systems written in different programming languages.\n- **Simplicity**: A straightforward and easy-to-use API.\n\n**packed** uses [umsgpack](https://github.com/vsergeev/u-msgpack-python), 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.\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Simple serialization and deserialization of custom Python objects using MessagePack",
"version": "0.3.0",
"project_urls": {
"Homepage": "https://github.com/tsv1/packed"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e38365369115a7c6d11d02d1f9c9283d9dd448d0f5e1b18bb80eafb2f6672a56",
"md5": "0ec111af87d1fd318d84696d8acc7372",
"sha256": "6bbe6a58e6c07dcb413fa8f27e233cdc4ac24f1d9f34fdb79de6e6f64758110f"
},
"downloads": -1,
"filename": "packed-0.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0ec111af87d1fd318d84696d8acc7372",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 11149,
"upload_time": "2024-09-19T16:08:55",
"upload_time_iso_8601": "2024-09-19T16:08:55.561780Z",
"url": "https://files.pythonhosted.org/packages/e3/83/65369115a7c6d11d02d1f9c9283d9dd448d0f5e1b18bb80eafb2f6672a56/packed-0.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2d38f702609d61a50a103715b4a80cc8fbaf7c528f68f80c86adf353f45848a2",
"md5": "795fcfbf00d4c986e9d06b5bd2d3a342",
"sha256": "e886688890085beacfac7d3f8f498ea1f153da19533c38a6db04ed0852773ea5"
},
"downloads": -1,
"filename": "packed-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "795fcfbf00d4c986e9d06b5bd2d3a342",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 11695,
"upload_time": "2024-09-19T16:08:57",
"upload_time_iso_8601": "2024-09-19T16:08:57.068376Z",
"url": "https://files.pythonhosted.org/packages/2d/38/f702609d61a50a103715b4a80cc8fbaf7c528f68f80c86adf353f45848a2/packed-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-19 16:08:57",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tsv1",
"github_project": "packed",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "u-msgpack-python",
"specs": [
[
">=",
"2.5"
],
[
"<",
"3.0"
]
]
}
],
"lcname": "packed"
}