Metadata-Version: 2.4
Name: pilpod
Version: 1.0.0
Summary: A lightweight binary data storage library for Python built using struct
License-Expression: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# PilPod

**A lightweight binary file format for storing named, typed data in Python.**

PilPod lets you save values into a binary `.pilp` file and retrieve them later, with support for multiple data types and byte orders.

## Features

- 📦 Store multiple named sections in a single file.
- 🔢 Support for numeric values and byte strings.
- 🔀 Configure byte order for individual sections.
- 🔄 Load and save data using a context manager.
- 🛡️ Detect malformed or truncated files.
- 🐍 Simple Python API.

## Installation

Install PilPod from PyPI:

```bash
python -m pip install pilpod
```

> If the published PyPI distribution has a different name, replace `pilpod` with its actual distribution name.

## Quick start

```python
from pilpod import PilPod, DataType, ByteOrder

# Create a file and add some sections.
with PilPod("example.pilp") as pod:
    pod.add(
        "greeting",
        b"Hello, world!",
        DataType.STRING,
        ByteOrder.LITTLE,
    )

    pod.add(
        "answer",
        42,
        DataType.SIGNED_INT,
        ByteOrder.LITTLE,
    )

# Reopen the file and read the saved values.
with PilPod("example.pilp") as pod:
    print(pod.get("greeting"))  # b'Hello, world!'
    print(pod.get("answer"))    # 42
```

Values are stored in a binary file, so strings represented by `DataType.STRING` are returned as `bytes` rather than automatically decoded into Python `str` objects.

## Supported data types

PilPod uses Python's `struct` format characters to represent its data types.

| `DataType` | Format | Description |
|---|---|---|
| `SIGNED_CHAR` | `b` | Signed character-sized integer |
| `UNSIGNED_CHAR` | `B` | Unsigned character-sized integer |
| `STRING` | `s` | Fixed-size byte string |
| `SIGNED_SHORT` | `h` | Signed short integer |
| `UNSIGNED_SHORT` | `H` | Unsigned short integer |
| `SIGNED_INT` | `i` | Signed integer |
| `UNSIGNED_INT` | `I` | Unsigned integer |
| `SIGNED_LONG` | `l` | Signed long integer |
| `UNSIGNED_LONG` | `L` | Unsigned long integer |
| `SIGNED_LONG_LONG` | `q` | Signed long long integer |
| `UNSIGNED_LONG_LONG` | `Q` | Unsigned long long integer |
| `FLOAT` | `f` | Floating-point number |
| `DOUBLE` | `d` | Double-precision floating-point number |

The accepted values and their sizes follow Python's `struct` packing rules and the selected byte order.

## Byte order

PilPod provides the following `ByteOrder` values:

| Value | Prefix | Description |
|---|---|---|
| `ByteOrder.LITTLE` | `<` | Little-endian, standard sizes |
| `ByteOrder.BIG` | `>` | Big-endian, standard sizes |
| `ByteOrder.NATIVE` | `@` | Native byte order, sizes, and alignment |
| `ByteOrder.NETWORK` | `!` | Network byte order, equivalent to big-endian |

Example:

```python
from pilpod import PilPod, DataType, ByteOrder

with PilPod("numbers.pilp") as pod:
    pod.add("little", 12345, DataType.SIGNED_INT, ByteOrder.LITTLE)
    pod.add("big", 12345, DataType.SIGNED_INT, ByteOrder.BIG)
```

## Reading and managing sections

Read a section by its name:

```python
with PilPod("example.pilp") as pod:
    value = pod.get("answer")
    print(value)
```

Delete a section:

```python
with PilPod("example.pilp") as pod:
    pod.delete("answer")
```

Section names are normalized internally before lookup. Attempting to access a nonexistent section raises `PilPodMissingSection`.

## File format

PilPod stores data in a custom binary format.

A file begins with a header containing the file magic and format version. Each section contains a section header followed by its name, byte-order information, and packed payload.

The section header uses the following structure:

```python
struct.Struct("<IIBI")
```

This records the name length, payload length, data type, and byte-order length.

The file header and section metadata allow PilPod to identify and parse stored values. Invalid or truncated data can raise `PilPodFileCorrupted`.

## Error handling

PilPod defines exceptions for problems encountered while reading or managing files.

For example:

```python
from pilpod import PilPod
from pilpod.errors import PilPodFileCorrupted, PilPodMissingSection

try:
    with PilPod("example.pilp") as pod:
        value = pod.get("missing")
except PilPodMissingSection:
    print("The requested section does not exist.")
except PilPodFileCorrupted:
    print("The file is invalid or truncated.")
```

Adjust the exception imports to match the public exports in your installed version.

## Requirements

- Python 3.11 or newer.
- The `pilpod` package.

Python 3.11+ is required for the `enum.StrEnum` API used by the project.

## License

PilPod is licensed under the **MIT License**.

See the [LICENSE](LICENSE) file for the complete license text.

## Contributing

Issues, bug reports, and improvements are welcome. Please use the project's issue tracker once its repository URL is published.
