packed


Namepacked JSON
Version 0.3.0 PyPI version JSON
download
home_pagehttps://github.com/tsv1/packed
SummarySimple serialization and deserialization of custom Python objects using MessagePack
upload_time2024-09-19 16:08:57
maintainerNone
docs_urlNone
authorNikita Tsvetkov
requires_python>=3.8
licenseApache-2.0
keywords
VCS
bugtrack_url
requirements u-msgpack-python
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 0.31361s