Skip to main content

Unbill Python bindings

After CI publishes a release, install it with python -m pip install unbill. Wheels target Linux x86_64 (glibc 2.28 or newer), macOS ARM64, and Windows x86_64. Use an in-process console directly, or connect to a separately installed daemon.

The Python package reuses the Rust console interface. Build it from the repository with Cargo and Python 3.9 or newer:

python3 bindings/python/build.py
python3 -m pip install ./target/python/debug

For an optimized build, add --release and install ./target/python/release. The output follows Cargo's target directory if you override it. Generated bindings and the native library stay under that directory and are not committed. The generator is built from the same pinned workspace dependencies as the library. The script fetches locked dependency sources before compilation so the embedded license catalog can include dependencies across all platforms.

The package includes a native shared library for the build host. Wheels are platform-specific (py3-none-<platform>), and require no Rust toolchain at runtime. To build a wheel for distribution:

python3 -m pip wheel --no-deps ./target/python/release -w ./target/python/wheels

Build separately for each supported operating system and architecture. Linux distribution may additionally require wheel repair with auditwheel; macOS may require delocate when the build links external shared libraries. The script builds for the Rust host target even if a cross-compilation target is configured.

Open an in-process console to run the Rust device service and SQLite storage inside Python, with no separate daemon:

import unbill

console = unbill.Console.open_in_process("./household-data")
ledger = console.create_ledger("Household", "USD")
detail = console.ledger_detail(ledger.ledger_id)
print(detail)

Alternatively, start unbill-daemon and connect to it:

console = unbill.Console.open_rpc(unbill.default_data_directory())

Both constructors provide the same operations. RPC uses the existing desktop data-directory configuration and UNBILL_SOCKET override. In-process mode uses the supplied directory directly and ignores UNBILL_SOCKET. A data directory can have only one storage owner: an in-process console or the daemon. Competing in-process opens raise unbill.ConsoleError.DataDirectoryInUse. Keep the in-process console alive while using it; releasing it stops its runtime and releases its storage ownership.

Records, enums, errors, and methods are generated from the same Rust exports used by Swift. Rust errors raise unbill.ConsoleError. Most methods are synchronous and block; use asyncio.to_thread when calling them from an asyncio application. sync_once is async and can be awaited directly.

Observers subclass unbill.ConsoleObserver and implement on_event(self, event). Keep the subscription returned by console.observe(observer) alive, then call subscription.cancel() when finished. Callbacks run on Rust worker threads: enqueue events or use loop.call_soon_threadsafe to forward them to the owning event loop before calling console methods.

Verify the generated package without installing it:

PYTHONPATH=target/python/debug python3 bindings/python/test_bindings.py

The default tests cover in-process operations, persistence, directory ownership, and observer delivery. For additional RPC verification, start a daemon with an isolated UNBILL_DATA_DIR, then set UNBILL_PYTHON_TEST_DIR to that same directory when running the tests. Use a temporary directory because this test creates a ledger.

CI and PyPI publishing

.github/workflows/python.yml builds, repairs, and tests wheels on relevant pull requests, pushes to main, and manual runs. Pushing a v* tag also publishes to PyPI after every platform passes. The tag must exactly match v followed by the Cargo workspace version. Package versions come from the workspace; nightly tags and manual runs do not publish. Rerunning a release skips files already on PyPI.

Linux wheels are built in manylinux_2_28 and repaired with auditwheel. macOS wheels use delocate, and Windows wheels use delvewheel to bundle external dependencies. CI installs the repaired wheels on Python 3.9 and 3.14 before uploading artifacts; Linux also tests Python 3.11. PyPI receives wheels only, so unsupported platforms use the repository build instructions above.

Publishing uses PyPI Trusted Publishing. Configure it once before pushing the first release tag:

  1. Create a GitHub Actions environment named pypi in unbill-project/unbill. Restrict its deployment tags to v*.

  2. In your PyPI account, open Publishing and add a pending GitHub publisher with these values:

    Field Value
    PyPI project name unbill
    Owner unbill-project
    Repository unbill
    Workflow filename python.yml
    Environment pypi

    If the PyPI project already belongs to you, add the publisher under that project's Publishing settings instead. A pending publisher creates the project on its first successful upload; it does not reserve the name.

  3. Push a version tag through the existing cargo release process. The Python workflow publishes alongside the existing application releases.

No PyPI API token or GitHub repository secret is required. Only the publishing job receives id-token: write; build and pull-request jobs have read permissions.

Metadata

Release files for unbill 0.0.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for unbill 0.0.8
File Interpreter ABI Platform
unbill-0.0.8-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
unbill-0.0.8-py3-none-manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64 Details
unbill-0.0.8-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details

Total release size: 32.9 MB

Release files / unbill-0.0.8-py3-none-win_amd64.whl

Download URL unbill-0.0.8-py3-none-win_amd64.whl
Size 8.9 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
f2c7adb809e33fd2b14ec0a52590e0869bb9334f30295f05e50c9f58b409a593
BLAKE2b-256 checksum
How to use checksums
cef7b3b2af31a9ee4c746b003747828b532877a74097be13c6c05574cc6048ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / unbill-0.0.8-py3-none-manylinux_2_28_x86_64.whl

Download URL unbill-0.0.8-py3-none-manylinux_2_28_x86_64.whl
Size 13.8 MB
Tags Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
72586fa56a31b96b2812707cb2164d021354bd8583c4ea2532da733e7b53952e
BLAKE2b-256 checksum
How to use checksums
6a3993c2292b0c3d1249e3a8fa53016ccebab19663c3416ee1d95eb61aad00ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / unbill-0.0.8-py3-none-macosx_11_0_arm64.whl

Download URL unbill-0.0.8-py3-none-macosx_11_0_arm64.whl
Size 10.2 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
cda6e844d8f5dbc2c8fb270c99d28266a8e0c8744528c6960fd44d50d248cd83
BLAKE2b-256 checksum
How to use checksums
d455e3674f1767305c1113021b66d662ac80361e0d791593e65a1668b42b3af2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for unbill 0.0.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 3 files in this release have been uploaded with provenance metadata.

Select from 3 files

Attestation for unbill-0.0.8-py3-none-win_amd64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.8 This release

3 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page