Metadata-Version: 2.4
Name: lsb32
Version: 0.1.0
Summary: Sortable seven-character timestamps backed by WebAssembly
License-Expression: LGPL-3.0-or-later
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: COPYING
Requires-Dist: wasmtime<47,>=46
Dynamic: license-file

# LSB32 for Python

`LSB32` converts timezone-aware Python `datetime` values into compact,
sortable, seven-character identifiers.

```text
2026-01-01 00:00:00 UTC -> D110000
```

The package handles epoch offsets, packed bits, Crockford symbols, padding,
WebAssembly calls, and calendar reconstruction internally.

## Installation

```console
pip install lsb32
```

## Quick start

```python
from datetime import datetime, timezone
from LSB32 import decode, encode

original = datetime(2026, 1, 1, tzinfo=timezone.utc)
value = encode(original)

assert value == "D110000"
assert decode(value) == original
```

## Current time

```python
from LSB32 import decode, now

value = now()
created = decode(value)
```

`now()` returns the encoded string directly. Decoding returns a timezone-aware
UTC `datetime` rounded to the encoded second.

## Custom epoch

The default epoch is 2000 and covers calendar years 2000 through 2063. Pass the
same custom epoch to both operations when another 64-year window is needed:

```python
from datetime import datetime, timezone
from LSB32 import decode, encode

original = datetime(2089, 12, 31, 23, 59, 59, tzinfo=timezone.utc)
value = encode(original, epoch=2026)
restored = decode(value, epoch=2026)

assert restored == original
```

The epoch is not stored in the identifier. Producers and consumers must use the
same value.

## API

| Function | Result |
| --- | --- |
| `encode(datetime, epoch=2000)` | Seven-character `str` |
| `decode(value, epoch=2000)` | UTC `datetime` |
| `now(epoch=2000)` | Current time as a seven-character `str` |

`encode` requires timezone information and converts the input to UTC. Subsecond
precision is discarded because the wire format stores whole seconds.

## Errors

```python
from LSB32 import Error, decode

try:
    decode("D110001")
except Error as failure:
    print(failure.code, failure)
```

`Error` reports invalid length, alphabet symbols, padding, date components, and
dates outside the configured epoch.

## Architecture

The wheel includes `lsb32.wasm` and `lsb32.wat`. Wasmtime executes the binary
module; WAT is included for inspection and reproducible tooling. The public API
does not expose raw integers or WASM status codes.

## Development

```console
python -m pip install -e .
python -m unittest discover -s tests
python -m build
python -m twine check dist/*
```

Regenerate shared artifacts from the repository root:

```console
node wasm.mjs
```

## Publishing

```console
python -m twine upload dist/*
```

Configure PyPI credentials before publishing.

## License

This package is licensed under the GNU Lesser General Public License, either
version 3 or any later version. See [LICENSE](LICENSE) and [COPYING](COPYING).
