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.2.0.tar.gz (34.0 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.2.0-py3-none-any.whl (30.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: deepidv_chain-1.2.0.tar.gz
  • Upload date:
  • Size: 34.0 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.2.0.tar.gz
Algorithm Hash digest
SHA256 77eb5b7affc309f54eb9586f474652c71e7d33389ae91fb2994540eaf5b04273
MD5 083b5ab2cd9b541c2e6b6ba097f3d770
BLAKE2b-256 2a7f4c59df2ab0cb6d141e0c70fdf8172ca658a1564e3c82913301a36fd4a405

See more details on using hashes here.

File details

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

File metadata

  • Download URL: deepidv_chain-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 30.9 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ff3f416ad2fd9dae5705d64cbf1776f339f77ea1dca90795ce280b41ba27a67a
MD5 caad64f3777b86e402ce00f947eed811
BLAKE2b-256 446c37073eceef02838280c17ccd8422cdcdadcdede034029e9d3f396d3ad4bf

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