Skip to main content

dryoc for Python

Don't Roll Your Own Crypto: High-performance, type-safe Pythonic bindings to dryoc, a pure-Rust cryptography library featuring up to 4x speedups over libsodium, modern post-quantum primitives, and full libsodium wire compatibility.

  • Authenticated encryption, public-key boxes, sealed boxes, encrypted streams, Ed25519 signatures, key exchange, Argon2 password hashing, BLAKE2b/SHA-2/SHA-3/SHAKE hashing, HMAC, HKDF, and post-quantum key encapsulation (ML-KEM-768 and X-Wing).
  • Output interoperates with libsodium (and so with PyNaCl, libsodium.js, and friends) wherever libsodium defines the format.
  • No C dependencies: libsodium is not needed at build or run time.
  • Typed (py.typed and complete stubs), with errors you cannot ignore by accident.

Installation

uv add dryoc

or pip install dryoc.

Prebuilt wheels are published for Linux x86_64 and aarch64 (glibc manylinux and musl/Alpine musllinux), macOS arm64 and Windows x86_64: one abi3 wheel per platform for CPython 3.11 and newer, plus a separate wheel for free-threaded CPython 3.14t. On other platforms (Intel macOS, Windows on ARM, PyPy) the installer builds from the source distribution, which needs a Rust toolchain, version 1.89 or newer.

Quick tour

Secret-key encryption

from dryoc.secretbox import SecretBox

key = SecretBox.generate()  # or SecretBox(existing_32_byte_key)
message = key.encrypt(b"attack at dawn")  # a random nonce is generated
ciphertext, nonce = message  # EncryptedMessage(ciphertext, nonce)
assert key.decrypt(ciphertext, nonce) == b"attack at dawn"
assert key.decrypt(*message) == b"attack at dawn"

Authenticated encryption with associated data

from dryoc.aead import XChaCha20Poly1305

key = XChaCha20Poly1305.generate()

# `seal` generates a nonce and returns one self-contained blob:
# nonce || ciphertext || tag.
envelope = key.seal(b"card number", associated_data=b"user 42")
assert key.open(envelope, associated_data=b"user 42") == b"card number"

# Or manage nonces yourself, in libsodium's ciphertext || tag format.
message = key.encrypt(b"card number", associated_data=b"user 42")
assert key.decrypt(*message, associated_data=b"user 42") == b"card number"

dryoc.aead.ChaCha20Poly1305 (RFC 8439) is also available; its 96-bit nonces are too short to pick at random, so it always takes an explicit nonce.

Public-key encryption

from dryoc.box import Box, KeyPair, SealedBox

alice, bob = KeyPair.generate(), KeyPair.generate()

# Authenticated: Bob knows the message came from Alice.
message = Box(alice, bob.public_key).encrypt(b"hi Bob")
assert Box(bob, alice.public_key).decrypt(*message) == b"hi Bob"

# Anonymous: anyone can encrypt to Bob; only Bob can decrypt.
sealed = SealedBox(bob.public_key).encrypt(b"a secret admirer")
assert SealedBox(bob).decrypt(sealed) == b"a secret admirer"

Post-quantum sealed boxes and key encapsulation

from dryoc.kem import xwing
from dryoc.sealedbox import SealedBox

recipient = xwing.KeyPair.generate()  # X-Wing: ML-KEM-768 + X25519

sealed = SealedBox(recipient.public_key).encrypt(b"store now, decrypt never")
assert SealedBox(recipient).decrypt(sealed) == b"store now, decrypt never"

ciphertext, shared_secret = recipient.public_key.encapsulate()
assert recipient.decapsulate(ciphertext) == shared_secret

dryoc.kem.mlkem768 offers ML-KEM-768 (FIPS 203) alone for protocols that require it.

Encrypted streams

from dryoc.secretstream import Decryptor, Encryptor, Key, Tag

key = Key.generate()
with Encryptor(key) as encryptor:
    header = encryptor.header
    chunks = [
        encryptor.push(b"first chunk"),
        encryptor.push(b"last chunk", tag=Tag.FINAL),
    ]

received = []
with Decryptor(key, header) as decryptor:
    for chunk in chunks:
        message, tag = decryptor.pull(chunk)
        received.append(message)
assert received == [b"first chunk", b"last chunk"]

Reordered, duplicated, dropped or modified chunks raise CryptoError. Used as context managers, both sides wipe their state on exit, and they raise if the block ends before the Tag.FINAL message, so a truncated stream is never mistaken for a complete one.

Signatures

from dryoc import CryptoError
from dryoc.sign import SigningKey

signing_key = SigningKey.generate()
signature = signing_key.sign(b"release v2.0.0")

verify_key = signing_key.verify_key  # share bytes(verify_key)
verify_key.verify(signature, b"release v2.0.0")  # returns None, or raises
try:
    verify_key.verify(signature, b"release v6.6.6")
except CryptoError:
    print("forgery detected")

dryoc.sign.Ed25519ph signs messages too large to hold in memory, incrementally.

Password hashing

from dryoc import CryptoError, pwhash, random_bytes

stored = pwhash.hash("correct horse battery staple")  # "$argon2id$v=19$..."
pwhash.verify(stored, "correct horse battery staple")  # raises CryptoError if wrong

salt = random_bytes(pwhash.SALT_SIZE)
key = pwhash.derive_key("passphrase", salt, strength=pwhash.Strength.MODERATE)
assert len(key) == 32

Presets are Strength.INTERACTIVE (the default), MODERATE and SENSITIVE, as in libsodium; opslimit and memlimit override them. Hashing runs with the GIL released.

Key exchange

from dryoc import kx
from dryoc.secretbox import SecretBox

client, server = kx.KeyPair.generate(), kx.KeyPair.generate()
client_keys = kx.client_session_keys(client, server.public_key)
server_keys = kx.server_session_keys(server, client.public_key)

message = SecretBox(client_keys.tx).encrypt(b"hello server")
assert SecretBox(server_keys.rx).decrypt(*message) == b"hello server"

Hashing

The hashers follow the hashlib interface; the lowercase functions are one-shot.

from dryoc import hash

assert hash.sha256(b"abc") == hash.Sha256(b"abc").digest()

h = hash.Blake2b(digest_size=32, key=b"k" * 32)  # keyed BLAKE2b
h.update(b"streamed ")
h.update(b"input")
tag = h.hexdigest()

xof = hash.TurboShake128(b"seed material")
reader = xof.reader()
first, second = reader.read(32), reader.read(32)

Blake2b follows libsodium's crypto_generichash, so its default digest is 32 bytes (hashlib.blake2b defaults to 64). Also available: Sha512, Sha3_256, Sha3_512, Shake128, Shake256 and TurboShake256.

MACs and key derivation

from dryoc import kdf, mac

key = mac.HmacSha512256.generate_key()
tag = mac.hmac_sha512256(key, b"message")
mac.HmacSha512256(key, b"message").verify(tag)  # constant time; raises on mismatch

master = kdf.Kdf.generate(context=b"MyApp v1")  # libsodium crypto_kdf
encryption_key, signing_seed = master.derive(1), master.derive(2)

okm = kdf.hkdf_sha256(b"input keying material", salt=b"salt", info=b"purpose")

mac also provides HmacSha256, HmacSha512 and the one-time authenticator Poly1305.

Conventions

  • Keys are objects. Create them with generate(), from raw bytes with Cls(data) / Cls.from_bytes(data), or (for key pairs) from_seed() and from_secret_key(). Wrong lengths raise InvalidInputError, which is a ValueError.
  • Secrets stay secret. Secret keys have a redacted repr, compare in constant time, are unhashable and unpicklable, and are wiped from memory when garbage-collected. Export them deliberately with bytes(key).
  • Failures raise. Every dryoc exception derives from dryoc.DryocError. Authentication, decryption and verification failures raise dryoc.CryptoError; nothing returns None or False to signal a forgery.
  • Any bytes-like input. bytes, bytearray, memoryview, array, NumPy arrays and other buffer-protocol objects are accepted; results are bytes. Mutable buffers are copied (and the copy wiped) before use, so another thread cannot change them mid-operation. A bytearray is copied atomically with respect to its own methods, even on free-threaded CPython; writing to other buffers (a memoryview, array, NumPy array) from another thread while a call copies them is a race, as with hashlib.
  • Threads. Password hashing and operations on inputs of 2 KiB or more run with the GIL released. Key objects are immutable; stateful objects (hashers, MACs, streams) serialize concurrent calls. The extension declares support for free-threaded CPython.

Compatibility

Formats match libsodium: crypto_secretbox_easy, crypto_box_easy, crypto_box_seal, crypto_aead_*chacha20poly1305_ietf, crypto_secretstream_xchacha20poly1305, crypto_sign (combined and detached), crypto_kx, crypto_kdf, crypto_generichash, crypto_pwhash_str and crypto_kem_xwing. The aead envelope (seal/open) and the post-quantum sealedbox use the formats of dryoc's Rust API; see the dryoc documentation.

Security

dryoc has not undergone a third-party security audit. Follow the documented nonce and key rules, and see the project repository for details.

License

MIT

Metadata

Release files for dryoc 2.0.0

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

Source distribution (sdist)

Source distribution for dryoc 2.0.0
File Size Uploaded
dryoc-2.0.0.tar.gz 1.3 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for dryoc 2.0.0
File
dryoc-2.0.0-cp314-cp314t-win_amd64.whl CPython 3.14 CPython 3.14 free-threading Windows x86-64 Details
dryoc-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ x86-64 Details
dryoc-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ ARM64 Details
dryoc-2.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64 Details
dryoc-2.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64 Details
dryoc-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64 Details
dryoc-2.0.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
dryoc-2.0.0-cp311-abi3-musllinux_1_2_x86_64.whl CPython 3.11 abi3 Linux musl 1.2+ x86-64 Details
dryoc-2.0.0-cp311-abi3-musllinux_1_2_aarch64.whl CPython 3.11 abi3 Linux musl 1.2+ ARM64 Details
dryoc-2.0.0-cp311-abi3-manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.28+ x86-64 Details
dryoc-2.0.0-cp311-abi3-manylinux_2_28_aarch64.whl CPython 3.11 abi3 Linux glibc 2.28+ ARM64 Details
dryoc-2.0.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details

Total release size: 12.2 MB

Release files / dryoc-2.0.0.tar.gz

Download URL dryoc-2.0.0.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
32ffa194ee2761f46ec48a8c882ae382500869aca5def9f248477647476f6b4b
BLAKE2b-256 checksum
How to use checksums
3fa1b431d53e76c865a9e199f9e5c72840e26b20ea360143b074d76bea781ca3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp314-cp314t-win_amd64.whl

Download URL dryoc-2.0.0-cp314-cp314t-win_amd64.whl
Size 852.0 kB
Tags CPython 3.14 CPython 3.14 free-threading Windows x86-64
SHA-256 checksum
How to use checksums
310c99fd15a9dbff3c3d28aa616c2fd6b7eb187bf5bf6fc9a67ebe6b3351f8fa
BLAKE2b-256 checksum
How to use checksums
38de661b1528ce6384646893066c424908fc42fb6f25bd0371907329d73757e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl

Download URL dryoc-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl
Size 1.0 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
96ab99dc30288115fa2977a906272f14b1083dd6eb393ac7d4b79e1cdb874a15
BLAKE2b-256 checksum
How to use checksums
b045eec75f51ab85d1cca1573e551883ed8b652dc28b6e6e6a207939f8496034
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl

Download URL dryoc-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl
Size 931.3 kB
Tags CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
3cc47f6b81699de4199deeae80e21297c637b89bdb1dab7c1c8490eb0579d0d7
BLAKE2b-256 checksum
How to use checksums
3bf80b998e76a4b41125b1bf9b0c02d46f5f960ea444c822785573c2c26335c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl

Download URL dryoc-2.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl
Size 949.4 kB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
8a04908d0ec16c9c3bdc4354c1cc5192b25a7f0a30e9bbaad6f0cbe18aa21c7f
BLAKE2b-256 checksum
How to use checksums
e6a2136430e876e00160df6fd98bc917df04498b6176a8089bb4d0d1b9d527c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl

Download URL dryoc-2.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl
Size 861.0 kB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
aed20f83ff2cc82455ee8f9f5d006420143f940f9d447fce80c99e4adaf317ac
BLAKE2b-256 checksum
How to use checksums
c8e3a2eddced00f29e3568d917b167d3d608864b69975f3ed70e3383ea2c5aab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl

Download URL dryoc-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl
Size 793.8 kB
Tags CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
159d98921aa38c27a9199ec3bea3d34dd7a6a1b2b2074c2491faffc8a8bebe1e
BLAKE2b-256 checksum
How to use checksums
8d984253dfc171b38ed840b2474e325028e2babf39961e63f8fddeec1c0de05e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp311-abi3-win_amd64.whl

Download URL dryoc-2.0.0-cp311-abi3-win_amd64.whl
Size 862.3 kB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
1c0759fca03eeb3a9b18042e1c062f81792507badf648f9ea8d7805dc48746c7
BLAKE2b-256 checksum
How to use checksums
35c80fd9673675541422a52e0cb309d9229cba49d265a91515ac1301108e6013
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp311-abi3-musllinux_1_2_x86_64.whl

Download URL dryoc-2.0.0-cp311-abi3-musllinux_1_2_x86_64.whl
Size 1.0 MB
Tags CPython 3.11 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
37d6fdf10da845899cdf5848cedd43b142699febefc71ba28ef617b7ffcd3843
BLAKE2b-256 checksum
How to use checksums
86668e71c5deae155405b34f6ec980c18f3b28c174a566af6c85553338122e72
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp311-abi3-musllinux_1_2_aarch64.whl

Download URL dryoc-2.0.0-cp311-abi3-musllinux_1_2_aarch64.whl
Size 937.4 kB
Tags CPython 3.11 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
82a6c8b855d894fb0c6743389f42fb3c46fc22e5ca3c3e87014851ac828c4583
BLAKE2b-256 checksum
How to use checksums
958c25f0e24fe9ef0d4ebd1e1c550561808faafb2468f77e26926456cb4a39da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp311-abi3-manylinux_2_28_x86_64.whl

Download URL dryoc-2.0.0-cp311-abi3-manylinux_2_28_x86_64.whl
Size 956.9 kB
Tags CPython 3.11 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
4db49cb40634285643f61a4bac33dd9e94ad152e9f50694e36980f4d7c0b88ad
BLAKE2b-256 checksum
How to use checksums
617802866aaf9e931833c726a48c318ed1e24301e41340c475b3b7f62954c0c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp311-abi3-manylinux_2_28_aarch64.whl

Download URL dryoc-2.0.0-cp311-abi3-manylinux_2_28_aarch64.whl
Size 868.3 kB
Tags CPython 3.11 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
c32153855cc397e0a995c2bdbd176a2bd653b592ef850b77a2431a56992c6153
BLAKE2b-256 checksum
How to use checksums
07a1c9ad9594024147a2a741f12367a270210e7b45ab1bed392d1bafd3e3c2c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release files / dryoc-2.0.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL dryoc-2.0.0-cp311-abi3-macosx_11_0_arm64.whl
Size 802.5 kB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
adcf835a9970f2a6f971793b57371456e069cbf71fd8f21e6380e2036ca6052e
BLAKE2b-256 checksum
How to use checksums
b9dcf3f6e41b587d078ac6b0f0ea0770bcc6457f5aae217099c4ee03d9bffb87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 28, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.0.0 This release

13 release files

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