Skip to main content

Binary codec library based upon muesli compile-time codecs

Project description

datacodec

Python 3.8+ Tests License Code style: black

A Python binary codec library based upon muesli compile-time codecs.

Installation

pip install datacodec

For NumPy support:

pip install datacodec[numpy]

Quick Start

The easiest way to use datacodec is with automatic codec generation from dataclasses:

from datacodec import dataclass_codec, BinaryFormat
from dataclasses import dataclass
import io

@dataclass
class Vec3:
    x: float  # Automatically uses double_codec
    y: float
    z: float

# Codec is automatically generated from type hints!
vec3_codec = dataclass_codec(Vec3)
format = BinaryFormat(vec3_codec)

# Serialize
output = io.BytesIO()
format.serialize(Vec3(1.0, 2.0, 3.0), output)

# Deserialize
output.seek(0)
result = format.deserialize(output)
print(result)  # Vec3(x=1.0, y=2.0, z=3.0)

Features

  • Automatic codec generation from dataclasses with type inference
  • Python-native types: int -> varint, float -> double, str -> string
  • NumPy support: Automatic detection of NumPy types (optional)
  • Fluent API: Chain codec operations with .transform(), .constrain(), .optional()
  • Cross-platform: Generate binary data for ARM32, ARM64, x86-32, x86-64 targets
  • Type-safe: Full Python typing support
  • Based on muesli: Binary compatible with muesli C++ library

Python Type Mappings

When using dataclass_codec(), Python types automatically map to appropriate codecs:

Python Type Codec Reason
int signed_varint_codec Python ints are arbitrary precision
float double_codec Python floats are double precision
bool bool_codec Boolean type
str string_codec UTF-8 strings

NumPy Types (with pip install datacodec[numpy])

NumPy Type Codec
np.int8/16/32/64 int8/16/32/64_codec
np.uint8/16/32/64 uint8/16/32/64_codec
np.float32 float_codec
np.float64 double_codec

Binary Format Details

String Encoding

Strings use null-termination (muesli compatible):

  • UTF-8 encoded string data
  • Null byte (0x00) terminator
# "hello" serialises as:
# [68 65 6c 6c 6f 00]
#  "hello" UTF-8  null

Integer Encoding

  • Fixed-size integers: Use native byte order and alignment
  • Varint: Variable-length encoding (1-10 bytes depending on value)
    • Unsigned: Direct varint encoding
    • Signed: Zigzag encoding (maps negatives to positives efficiently)

Alignment

Platform-specific alignment is maintained:

  • ARM32: 8-byte alignment for int64/double
  • ARM64: 8-byte alignment for int64/double
  • x86-64: Natural alignment per type

Examples

Automatic Codec Generation

from datacodec import dataclass_codec
from dataclasses import dataclass

@dataclass
class Person:
    name: str      # -> string_codec
    age: int       # -> signed_varint_codec
    height: float  # -> double_codec

# Codec automatically generated!
person_codec = dataclass_codec(Person)

Explicit Fixed-Size Types

Use the @codec decorator when you need specific fixed-size types:

from datacodec import dataclass_codec, codec, uint8_codec, uint32_codec

@dataclass
class Message:
    msg_type: int = codec(uint8_codec)      # Force uint8
    timestamp: int = codec(uint32_codec)    # Force uint32
    payload_size: int                       # Uses varint (default)

protocol_codec = dataclass_codec(Message)

Manual Codec Construction

For full control, build codecs manually:

from datacodec import tuple_codec, float_codec, BinaryFormat

@dataclass
class Vec3:
    x: float
    y: float
    z: float

# Manually specify each field's codec
vec3_codec = tuple_codec(float_codec, float_codec, float_codec).apply(Vec3)

Dict Codec

Python dicts work like std::map in muesli - no special codec needed, just composition:

from datacodec import dict_codec, string_codec, int32_codec

# Dict[str, int]
my_dict_codec = dict_codec(string_codec, int32_codec)
data = {"a": 1, "b": 2, "c": 3}

Cross-Platform

Generate binary data for different architectures:

from datacodec import BinaryFormat, uint32_codec

# Generate data for ARM32 target
format_arm32 = BinaryFormat(uint32_codec, platform='arm32')

# Binary is compatible with muesli C++ on ARM32

Fluent API

Chain transformations and constraints:

from datacodec import int32_codec

validated = int32_codec \
    .constrain(lambda x: x > 0) \
    .transform(lambda x: x * 2, lambda x: x // 2) \
    .optional()

Advanced Usage

NumPy Arrays

import numpy as np
from datacodec import numpy_array_codec

# Fixed-size 3D vector
vec3 = numpy_array_codec(np.float32, shape=(3,))

# Dynamic-size array
float_array = numpy_array_codec(np.float32)

NumPy in Dataclasses

import numpy as np
from datacodec import dataclass_codec

@dataclass
class Point:
    x: np.float32  # Automatically uses float_codec
    y: np.float32
    z: np.float32

point_codec = dataclass_codec(Point)

License

BSD 3-Clause License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

datacodec-1.0.0.tar.gz (39.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

datacodec-1.0.0-py3-none-any.whl (33.7 kB view details)

Uploaded Python 3

File details

Details for the file datacodec-1.0.0.tar.gz.

File metadata

  • Download URL: datacodec-1.0.0.tar.gz
  • Upload date:
  • Size: 39.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for datacodec-1.0.0.tar.gz
Algorithm Hash digest
SHA256 6a471e449d9c520695aee0ef8d59eb204f9956658a908c61f6173830c656cea7
MD5 698bcf5d12854d6c10ecc464f85d9323
BLAKE2b-256 34e1a720ac03bf2ae19c0774dba0b6f36497db15e68c0d628ff3d4c28fb88e1c

See more details on using hashes here.

File details

Details for the file datacodec-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: datacodec-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 33.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for datacodec-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fc276104bdc469810918150c405ab47b4d4ed20b9d41327d354512123b123c27
MD5 6ee915b9fff51d201d7b90fdcd2bb990
BLAKE2b-256 05426eb6559bd557fc425dbb46b438dd987bf65090ad30829092ba8e28c7a734

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page