Skip to main content

hashsign-python

Official Python SDK for HashSign — hash documents locally, request cryptographic verification payloads, and retrieve Hedera Hashgraph audit proofs. Designed for AI agents that need programmatic, auditable signing.

Requires Python 3.10+.

Install

pip install hashsign-python

From this monorepo:

cd sdks/python
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Quickstart

from hashsign import HashSignClient

client = HashSignClient(api_key="hs_live_...")

document = client.documents.upload("contract.pdf")
signed = client.documents.sign(document.id, metadata={"agentId": "invoice-bot"})
proof = client.documents.verify(document.id)

print(signed.payload.signature, signed.document.status)
print(proof.hedera_transaction_id, proof.verified)

sign() returns the full SignDocumentResponse from the API — .payload is the detached signature, .document reflects the new status.

Hybrid ML-DSA-65 envelope

Pass pqc_mode=True when the API key has requirePqcSignatures or when you want a hybrid-ecdsa-ml-dsa envelope. The post-quantum half is FIPS 204 ML-DSA-65 over the raw 32-byte SHA-256 digest (pure ML-DSA, not HashML-DSA). The signature is 3309 bytes. Hedera Consensus Service stores only the 32-byte hybrid anchor, because topic messages are capped at 1024 bytes. The landing-page example topic is 0.0.9001; live topics come from the proof's topic_id.

signed = client.documents.sign(document.id, pqc_mode=True)
proof = client.documents.verify(document.id)

Recompute the anchor locally and compare it to the HCS message field hybridAnchor:

import hashlib

payload = signed.payload
anchor = hashlib.sha256(
    f"{payload.signature}{payload.pqc.signature}".encode()
).hexdigest()
assert anchor == payload.pqc.hybrid_anchor

payload.pqc.public_key is the 1952-byte ML-DSA-65 public key (hex). Verify the signature over the raw digest bytes with any FIPS 204 implementation. The Python SDK requests the envelope; it does not bundle a lattice library.

Async

import asyncio
from hashsign import AsyncHashSignClient

async def main() -> None:
    async with AsyncHashSignClient(api_key="hs_live_...") as client:
        document = await client.documents.upload("contract.pdf")
        await client.documents.sign(document.id)
        proof = await client.documents.verify(document.id)
        print(proof.network, proof.verified)

asyncio.run(main())

Rotate agent credentials

rotated = client.keys.rotate()
print(rotated.key.secret)  # shown once — persist immediately

Configuration

Argument Default Description
api_key required hs_live_... or hs_test_...
base_url https://api.hashsign.io/v1 API origin including /v1
timeout 30.0 httpx timeout (seconds)
transport None Custom httpx transport (tests)

Errors

All failures — HTTP status errors, transport failures, and malformed responses — subclass HashSignError, so one except HashSignError boundary is sufficient:

  • AuthenticationError — invalid or revoked key (401 / 403)
  • ValidationError — request / hash mismatch (400 / 422), or malformed local metadata
  • RateLimitError — includes retry_after_seconds (429)
  • HederaNetworkError — consensus or mirror-node outage (502 / 503)
  • NotFoundError / ConflictError
  • APIConnectionError — DNS, refused connection, TLS; wraps httpx.TransportError
  • APITimeoutError — subclass of APIConnectionError for connect / read timeouts
  • InvalidResponseError — 2xx body that is not JSON, empty, or fails schema validation

In the async client, file hashing runs in a worker thread (asyncio.to_thread) so large uploads never block the event loop.

Local crypto

hashsign.crypto hashes files with SHA-256 and can produce detached Ed25519 signatures. Production deployments should swap those helpers for Hedera operator-key signing (hedera-sdk-py) at the marked HOOK comments.

Tests

pytest

The suite uses httpx.MockTransport and does not call a live API or Hedera network. tests/test_contract.py additionally validates every request body the SDK emits against packages/shared/openapi.yaml, so SDK/spec drift fails CI.

Metadata

Release files for hashsign-python 0.1.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 hashsign-python 0.1.0
File Size Uploaded
hashsign_python-0.1.0.tar.gz 6.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for hashsign-python 0.1.0
File Interpreter ABI Platform
hashsign_python-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 6.4 MB

Release files / hashsign_python-0.1.0.tar.gz

Download URL hashsign_python-0.1.0.tar.gz
Size 6.4 MB
Tags Source
SHA-256 checksum
How to use checksums
9c0105d79bcd71e22481365661622af63f856cb22db52c5ea7088525ca56bfef
BLAKE2b-256 checksum
How to use checksums
e39a481c29894c56f3961c110f1e67c7a9d0d3a1c5788e5d3b335376aa4271f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / hashsign_python-0.1.0-py3-none-any.whl

Download URL hashsign_python-0.1.0-py3-none-any.whl
Size 14.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b672645bd4cae5665b903b27f974d03636ac748eb42e9e5b8057169c3804a3d6
BLAKE2b-256 checksum
How to use checksums
62cbd05bce6048000dfa9ec19af1446cb402bf47d246ef90fff54f43e2a16f3a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 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