Skip to main content

Python SDK for the deepidv chain layer — attestations, registry, transparency log, and offline bundle verification.

Project description

deepidv-chain

Python SDK for the deepidv chain layer — read the public attestation registry, follow the transparency log, and verify offline .dpiv-bundle archives end-to-end.

pip install deepidv-chain
  • Sync and async clients (Client, AsyncClient) over httpx.
  • Offline bundle verification (verify_bundle) — RFC 6962 inclusion + RFC 8785 envelope hash + ECDSA P-256 manifest and STH signatures.
  • Pydantic v2 models throughout. Fully typed (py.typed), passes mypy --strict.
  • Cross-language parity with the Node SDK (@deepidv/chain): byte-identical hashes for the same fixtures.
  • Python 3.9 → 3.13.

Quickstart — sync

from deepidv_chain import Client

with Client("https://staging-api.deepidv.com") as chain:
    # Pull a single attestation by id.
    attestation = chain.get_attestation("attest_01J9X9YQ7W7N2T0M5K8P3R4Q6V")
    print(attestation.record_type, attestation.issuer_id)

    # Page through the public registry.
    page = chain.list_registry({"record_type": "IDV"})
    for summary in page.items:
        print(summary.attestation_id, summary.issued_at)

    # Download the offline-verifiable bundle.
    bundle_bytes = chain.download_bundle(attestation.attestation_id)

Quickstart — async

import asyncio
from deepidv_chain import AsyncClient

async def main():
    async with AsyncClient("https://staging-api.deepidv.com") as chain:
        log = await chain.get_log()
        for segment in log.segments:
            print(segment.segment_id, segment.tree_size)

asyncio.run(main())

Streaming — Server-Sent Events

async with AsyncClient() as chain:
    async for event in chain.stream_attestations():
        print(event.event, event.id, event.data)

The iterator reconnects with exponential backoff on transient disconnects and replays Last-Event-ID so the server can resume. Pass max_reconnect_attempts=0 to disable reconnection.

Offline bundle verification

from deepidv_chain import verify_bundle

with open("attestation.dpiv-bundle", "rb") as f:
    result = verify_bundle(f.read())

if result.valid:
    print("verified:", result.attestation_id)
else:
    for check in result.checks:
        if not check.passed and not check.skipped:
            print(f"FAIL {check.name}: {check.detail}")

verify_bundle runs a 5-of-6 contract end-to-end:

  1. Manifest integrity (sha256sum-compatible).
  2. Manifest signature (chain-master ECDSA P-256).
  3. Envelope hash (sha256(JCS(envelope))).
  4. RFC 6962 inclusion proof reconstructs the STH root.
  5. STH signature (chain-master ECDSA P-256 over the JCS-canonical unsigned form).
  6. TSA timestamp — SKIPPED in v1. Reported as skipped=True, passed=False. The detail string explicitly notes whether timestamp.tsr was present or absent. Never silently treated as a pass. If your policy requires a trusted external timestamp, treat the skip as a non-pass and gate accordingly.

result.envelope is the envelope dict with the per-record privacy salt stripped — safe to render directly. The full envelope (with salt) is what the verifier hashes; do not reconstruct it from result.envelope for a re-hash.

Errors

from deepidv_chain import (
    DeepidvApiError,         # base
    DeepidvAuthError,        # 401 / 403
    DeepidvNotFoundError,    # 404
    DeepidvRateLimitError,   # 429 (carries .retry_after_seconds)
    DeepidvServerError,      # 5xx
)

Every error carries status_code, url, body, and request_id (from the x-request-id response header).

Type checking

The package ships a py.typed marker and is fully type-annotated. The typed surface lives at deepidv_chain (top-level re-exports) and deepidv_chain.types.

from deepidv_chain import AttestationDetail, RegistryFilters

Configuration

Client(
    api_url="https://api.proof.deepidv.com",   # default: staging-api.deepidv.com
    api_key="dpiv_live_...",                   # bearer token; optional for public reads
    timeout=30.0,                              # httpx timeout
    user_agent="my-app/1.0",                   # appended User-Agent
    http_client=my_pre_configured_httpx,       # inject your own httpx.Client
)

The same kwargs apply to AsyncClient (with httpx.AsyncClient).

Cross-language parity

Hashes computed by this SDK are byte-identical to those computed by @deepidv/chain for the same logical input. The shared parity fixtures live in tests/fixtures/jcs-vectors.json and tests/fixtures/envelope-hashes.json. If you discover a divergence, file an issue with the offending input — both SDKs gate releases on parity.

Privacy

  • Bundle-verify return values never include the per-record privacy salt.
  • claim_hash is sha256 over the JCS-canonical claim and is intentionally one-way.
  • The SDK never logs claim bodies, salts, or signatures.

License

Apache-2.0. See LICENSE.

Links

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

deepidv_chain-1.0.0.tar.gz (33.8 kB view details)

Uploaded Source

Built Distribution

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

deepidv_chain-1.0.0-py3-none-any.whl (30.8 kB view details)

Uploaded Python 3

File details

Details for the file deepidv_chain-1.0.0.tar.gz.

File metadata

  • Download URL: deepidv_chain-1.0.0.tar.gz
  • Upload date:
  • Size: 33.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for deepidv_chain-1.0.0.tar.gz
Algorithm Hash digest
SHA256 83a92cb3cbd36903001da0eac23ade6f41bfd3ac37872aafe32cca31532a15f6
MD5 68bef625a565991d43febdf721875075
BLAKE2b-256 8a41715beadd0fe4d7c6338aba3d1f6b52ca31639998268cb9469610ab85b22d

See more details on using hashes here.

File details

Details for the file deepidv_chain-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: deepidv_chain-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 30.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for deepidv_chain-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 de59394729e0bebc179dcea16b3cd1ea27b8231a84305f05c23c6ca5f8d8e865
MD5 c1d6f915d407d14a953b81150bd1a84a
BLAKE2b-256 8a4f45c3b1852d983e4b9d00f6db02f302103b44a477cc9c3e727ae4079c7fb6

See more details on using hashes here.

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