Skip to main content

Python bindings for the Rust multiformats implementations (multibase, multihash, multiaddr, CID)

Project description

py-multiformats

CI PyPI Python versions License: Apache-2.0 Built with PyO3

Python bindings for the official Rust multiformats implementations, wrapped with PyO3:

The package also embeds the canonical multicodec and multibase registries, compiled in at build time from the vendored tables in data/ and refreshed weekly from upstream.

Contents

Why this package?

The existing Python options are four single-format packages (py-multibase, py-multihash, py-multiaddr, py-cid) that have mostly gone quiet, and the pure-Python multiformats package. This one puts all four formats behind a single typed API and lets the Rust reference implementations do the actual work (the same code that runs inside rust-libp2p). Spec fixes arrive by bumping a dependency, parsing and hashing run at native speed, and the codec tables are generated from the canonical registries instead of being copied in once and left to rot. Ships as prebuilt abi3 wheels for CPython ≥ 3.10, no runtime dependencies.

Install

pip install py-multiformats

Usage

from multiformats import multibase, multicodec, multihash
from multiformats.cid import CID
from multiformats.multiaddr import Multiaddr
from multiformats.multihash import Multihash

# multicodec — the codec registry. Every entry is a module constant.
multicodec.DAG_PB                                    # 112 (0x70)
multicodec.code("dag-pb")                            # 112, name -> code
multicodec.name(multicodec.DAG_PB)                   # "dag-pb"
multicodec.tag(multicodec.DAG_PB)                    # "ipld" (accepts constant, code, or name)
multicodec.entries()                                 # [(name, tag, code, status), ...]

# multibase — constants hold the canonical encoding names
encoded = multibase.encode(multibase.BASE58BTC, b"hello")   # "zCn8eVZg"
base, data = multibase.decode(encoded)               # ("base58btc", b"hello")
base == multibase.BASE58BTC                          # True
multibase.bases()                                    # all supported encodings

# multihash
mh = multihash.digest(multicodec.SHA2_256, b"hello world")
mh = multihash.sha2_256(b"hello world")              # same, via convenience function
mh.code == multicodec.SHA2_256                       # True
mh.name                                              # "sha2-256"
mh.size                                              # 32
mh.digest                                            # raw digest bytes
Multihash.from_bytes(mh.to_bytes()) == mh            # True
multihash.codes()                                    # name -> code table

# CID
cid = CID.decode("QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n")
cid.version                                          # 0
cid.codec == multicodec.DAG_PB                       # True
cid.codec_name                                       # "dag-pb"
cid.hash.name                                        # "sha2-256"
CID(1, multicodec.RAW, cid.hash)                     # codec by constant, code, or name
str(cid.to_v1())                                     # "bafybeihdwdce..."
cid.to_v1().encode(multibase.BASE64URL)              # any multibase encoding
CID.from_bytes(cid.to_bytes()) == cid                # True

# multiaddr
addr = Multiaddr("/ip4/127.0.0.1/tcp/4001")
list(addr)                                           # [("ip4", "127.0.0.1"), ("tcp", "4001")]
addr.protocols()                                     # ["ip4", "tcp"]
addr = addr.encapsulate("/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC")
addr.decapsulate("/tcp/4001")                        # Multiaddr("/ip4/127.0.0.1")
Multiaddr.from_bytes(addr.to_bytes()) == addr        # True

Anything that fails to parse, decode, or encode raises multiformats.MultiformatsError, a subclass of ValueError.

Development

You need a Rust toolchain and uv:

uv sync                                       # create the venv, install the dev tools, build the extension
uv run pytest                                 # run the test suite
uv run mypy tests/                            # type-check against the stubs
uv run maturin develop                        # rebuild the extension after Rust changes
cargo clippy --all-targets -- -D warnings     # lint the Rust side
cargo test                                    # run the Rust unit tests

The dev tools (maturin, pytest, mypy) are declared as a dependency group in pyproject.toml, so uv sync installs everything.

Code generation

The multicodec and multibase registries are not hand-written. The canonical tables are vendored in data/:

build.rs turns both CSVs into Rust at build time: the registry rows as a static ENTRIES table, phf perfect hash maps for the lookups, and a consts module with one constant per entry. The same entries become the Python constants (multicodec.DAG_PB, multibase.BASE58BTC, ...) at import time. build.rs also writes the multicodec.pyi and multibase.pyi stubs — those are committed and CI fails if they drift, so IDE autocomplete always matches the vendored tables.

To pull the latest tables from upstream:

./scripts/update-tables.sh

A scheduled workflow (update-tables.yml) runs the same script weekly and opens a pull request when a registry changed.

Releasing

Releases are tag-driven; nothing is built or uploaded from a laptop.

  1. Bump version in pyproject.toml (PEP 440, e.g. 0.1.0a1 for an alpha, 0.1.0 for a final release) and mirror it in Cargo.toml (0.1.0-alpha.1 in semver). Commit and push.

  2. Tag the commit and push the tag:

    git tag v0.1.0a1
    git push origin v0.1.0a1
    
  3. The release workflow triggers on v* tags: it builds abi3 wheels for Linux (manylinux + musllinux, x86_64/aarch64), macOS (x86_64/arm64), and Windows (x64), builds the sdist, and publishes everything to PyPI.

Publishing uses trusted publishing (OIDC) — there are no PyPI tokens anywhere. One-time setup, already done for this repository: a (pending) publisher on PyPI pointing at probe-lab/py-multiformats, workflow release.yml, environment pypi, and a matching pypi environment in the GitHub repository settings.

License

Apache-2.0

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

py_multiformats-0.1.0a1.tar.gz (75.2 kB view details)

Uploaded Source

Built Distributions

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

py_multiformats-0.1.0a1-cp310-abi3-win_amd64.whl (383.8 kB view details)

Uploaded CPython 3.10+Windows x86-64

py_multiformats-0.1.0a1-cp310-abi3-musllinux_1_2_x86_64.whl (692.0 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

py_multiformats-0.1.0a1-cp310-abi3-musllinux_1_2_aarch64.whl (636.6 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

py_multiformats-0.1.0a1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (474.3 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

py_multiformats-0.1.0a1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (459.7 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

py_multiformats-0.1.0a1-cp310-abi3-macosx_11_0_arm64.whl (414.1 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

py_multiformats-0.1.0a1-cp310-abi3-macosx_10_12_x86_64.whl (457.8 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file py_multiformats-0.1.0a1.tar.gz.

File metadata

  • Download URL: py_multiformats-0.1.0a1.tar.gz
  • Upload date:
  • Size: 75.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for py_multiformats-0.1.0a1.tar.gz
Algorithm Hash digest
SHA256 64fe823876b91ada887fbc892c2e97ee0a6187d1c804d0914c7dc5218b40cbbb
MD5 6a4c5294abf950c362f55482d8bb1548
BLAKE2b-256 3a33b9906831b4d1601e100fef0754f150c24e563afaff969207d48784a7304c

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_multiformats-0.1.0a1.tar.gz:

Publisher: release.yml on probe-lab/py-multiformats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_multiformats-0.1.0a1-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for py_multiformats-0.1.0a1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 2b2bb0ae2f832b893ac8d6f70e8a37933479f84119260eb28972b9db3b0848e5
MD5 001f72983802f8e9d0e824f781469507
BLAKE2b-256 20795290e28cc2207a654c308198938d03c02b429e309a87295a8288401b87e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_multiformats-0.1.0a1-cp310-abi3-win_amd64.whl:

Publisher: release.yml on probe-lab/py-multiformats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_multiformats-0.1.0a1-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for py_multiformats-0.1.0a1-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 fc8639a2517db2abd0373ed23cafe927371d9bccc3c14e6ab8113a068ce74015
MD5 f89a05592387eb963fabf40c49cb68c5
BLAKE2b-256 833e125d48b3d6be58299ce98f5cd08db7179c0c1abf06b3654de6fb7157d17e

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_multiformats-0.1.0a1-cp310-abi3-musllinux_1_2_x86_64.whl:

Publisher: release.yml on probe-lab/py-multiformats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_multiformats-0.1.0a1-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for py_multiformats-0.1.0a1-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 f4795b50b4943f622aee71dd7cc6c18c0db3e8c4b7e7367756e95dcf602e5c57
MD5 950c283445f29c886ecfcbb395c861cc
BLAKE2b-256 d9cbe6d5bce95bd65d9f102cbdbc28cd70fb3ef9f5d658e7df106dcea4ca49b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_multiformats-0.1.0a1-cp310-abi3-musllinux_1_2_aarch64.whl:

Publisher: release.yml on probe-lab/py-multiformats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_multiformats-0.1.0a1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for py_multiformats-0.1.0a1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 64115aabc534d3ee794adb69442081b33d2f736339efee02bb7074784f017f6e
MD5 dba7ea9bc5b94ead822962e59c018bde
BLAKE2b-256 b91935a002cf4d9531400a3c8b7ec51ba484cd21e04d5498a426e12948b955c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_multiformats-0.1.0a1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on probe-lab/py-multiformats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_multiformats-0.1.0a1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for py_multiformats-0.1.0a1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5d705c6be5b16c0d7e0c1bb8ce25c02e91aacef6e5689b5b212ab27a5d731a8b
MD5 c06adb54dee09f68837ecf5653183193
BLAKE2b-256 1551bc7dbd40768ffb61e4328d9cc88b6aa66bd1d07f41c118660044fae33386

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_multiformats-0.1.0a1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on probe-lab/py-multiformats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_multiformats-0.1.0a1-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for py_multiformats-0.1.0a1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3852d05466416db9b7190cebd6649b498e3e3a307fff227e423cbb86eb30a635
MD5 991a0a087589a5cb7f3dc13d29f5b2ef
BLAKE2b-256 2805959812a8335dee714f9fbcd7da2c00c05f3e7f82f16a88be9f691e016cc9

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_multiformats-0.1.0a1-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on probe-lab/py-multiformats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_multiformats-0.1.0a1-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for py_multiformats-0.1.0a1-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f5c5d42dfa2cb9c97d10c12fca39d1278b072fa3840d01c36f16fe74fafcdd03
MD5 1b6f083c2f80e87a3442e54b03847727
BLAKE2b-256 3aaa852950f271f315447911d99b5e9fafd2a4c65e3dbf21c89b4c3520923301

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_multiformats-0.1.0a1-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on probe-lab/py-multiformats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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