acdp — Python SDK
Python bindings for ACDP (acdp-py)
Thin PyO3 binding over the acdp Rust
library. Implements the producer- and consumer-side crypto for the Agent
Context Distribution Protocol v0.1.0 (RFC-ACDP-0001/0003/0008). HTTP is
intentionally left to the caller — pair this with httpx / requests
for transport.
Install (development)
pip install maturin
maturin develop # editable install into the active venv
pytest tests/ # in-process unit tests, no HTTPBuild a wheel
maturin build --release # produces target/wheels/acdp-*.whl
pip install target/wheels/acdp-0.1.0-*.whlQuickstart
import json, acdp
producer = acdp.AcdpProducer.generate(
"did:web:agents.example.com:my-agent",
"did:web:agents.example.com:my-agent#key-1",
)
raw = producer.build_publish_request(
title="Q1 snapshot",
context_type="data_snapshot",
summary="Quarter-end inventory",
)
request = json.loads(raw)
# POST `raw` (the JSON string) to the registry's /v1/contexts endpoint
# with your HTTP client of choice. On retrieve, validate the response:
body = ... # response.json()["body"]
acdp.AcdpVerifier.verify_content_hash(json.dumps(body), body["content_hash"])
acdp.AcdpVerifier.verify_signature(
pub_key_b64, # resolved from the producer's did:web doc
body["signature"]["value"],
body["content_hash"],
)Design rules
- JSON across the FFI boundary. Every method accepts and returns JSON strings — never a Rust type, never a Python dataclass. The wheel stays at ~500 lines of glue.
- Crypto in Rust, HTTP in Python. Key generation, JCS + SHA-256
hashing, Ed25519 signing, and signature verification all happen in
the underlying
acdpcrate. The Python side handles transport, retries, and observability. AcdpProducerstores a 32-byte seed. The RustSigningKeyisZeroizeOnDropand notClone, so the binding rebuilds the signing key from the seed on each call.- Golden vector parity.
test_golden_content_hashpins the Python-sidecontent_hashandsignature.valueagainst the spec'ssig-001fixture — the same constants the Rust suite asserts. A drift on either side is a protocol break.
Layout
bindings/acdp-py/
├── Cargo.toml # standalone [workspace]; depends on `acdp` via path
├── pyproject.toml # maturin build backend
├── README.md # this file
├── src/
│ ├── lib.rs # #[pymodule] entry point
│ ├── producer.rs # AcdpProducer: build/sign publish requests
│ ├── verifier.rs # AcdpVerifier: content_hash + signature verify
│ └── helpers.rs # visibility / context_type string parsers
└── tests/
└── test_producer.py