Skip to main content

ETH.id Python SDK

Zero-Knowledge Document Verification SDK for Python.

Installation

pip install ethid

Quick Start

from ethid import EthIdClient, LLMProvider

# Initialize client
client = EthIdClient(
    provider=LLMProvider.OPENAI,
    api_key="sk-your-key"
)

# Verify a document
result = client.verify(
    document_path="passport.pdf",
    claim="over 18 years old"
)

print(f"Answer: {result.answer}")
print(f"Confidence: {result.confidence}%")
print(f"Reasoning: {result.reasoning}")

Features

  • Zero-Knowledge Verification: Documents never leave your machine
  • Privacy-First: Only minimal, claim-relevant data is processed
  • Multiple LLM Providers: OpenAI, Claude, Ollama
  • Cryptographic Attestations: Tamper-evident proof bundles
  • Audit Trail: Complete verification history
  • Type-Safe: Full type hints and dataclasses

Usage

Basic Verification

from ethid import EthIdClient

client = EthIdClient()

# Age verification
result = client.verify(
    document_path="id.pdf",
    claim="maior de 18 anos"
)

if result.answer:
    print("Person is over 18")

With Attestation

# Generate cryptographic proof
result = client.verify(
    document_path="id.pdf",
    claim="over 21 years old",
    attest=True
)

# Get attestation bundle
bundle = client.get_attestation(result.session_id)

# Verify integrity
if bundle.verify_integrity():
    print("Attestation is valid")

Offline Mode

# Complete privacy with local LLM
client = EthIdClient(
    provider=LLMProvider.OLLAMA,
    offline=True
)

result = client.verify(
    document_path="document.pdf",
    claim="document is signed"
)

Audit Log

# List all verifications
entries = client.list_audit_log(limit=10)

for entry in entries:
    print(f"{entry.timestamp}: {entry.claim} -> {entry.answer}")

# Get specific entry
entry = client.get_audit_entry(session_id="...")

Privacy Guarantees

What is NEVER Sent

For age verification:

  • ❌ Birth date
  • ❌ Full name
  • ❌ Address
  • ✅ Only: "Age calculation result: true"

For CPF verification:

  • ❌ Full CPF (123.456.789-00)
  • ✅ Only: Masked (123..-00)

API Reference

EthIdClient

class EthIdClient:
    def __init__(
        self,
        cli_path: Optional[str] = None,
        provider: Optional[LLMProvider] = None,
        api_key: Optional[str] = None,
        offline: bool = False,
        debug: bool = False,
    )

Methods

verify()

def verify(
    self,
    document_path: str,
    claim: str,
    provider: Optional[LLMProvider] = None,
    attest: bool = False,
    zk_only: bool = False,
) -> VerificationResult

get_attestation()

def get_attestation(
    self,
    session_id: str,
) -> AttestationBundle

list_audit_log()

def list_audit_log(
    self,
    limit: Optional[int] = None,
    filter_claim: Optional[str] = None,
) -> List[AuditEntry]

configure()

def configure(
    self,
    provider: Optional[LLMProvider] = None,
    api_key: Optional[str] = None,
)

Types

VerificationResult

@dataclass
class VerificationResult:
    session_id: str
    answer: bool
    confidence: float
    reasoning: str
    proof_type: ProofType
    claim: str
    privacy_metadata: PrivacyMetadata
    timestamp: datetime

AttestationBundle

@dataclass
class AttestationBundle:
    session_id: str
    document_hash: str
    claim: str
    result: VerificationResult
    proof_type: ProofType
    bundle_hash: str
    created_at: datetime
    
    def verify_integrity(self) -> bool

Examples

Age Verification

result = client.verify(
    document_path="passport.pdf",
    claim="over 18 years old"
)

print(f"Over 18: {result.answer}")

CPF Verification

result = client.verify(
    document_path="brazilian_id.pdf",
    claim="CPF bate com 123.456.789-00"
)

# Only masked CPF is sent: 123.***.***-00

Income Verification

result = client.verify(
    document_path="income_proof.pdf",
    claim="renda acima de 5000"
)

# Only amount field is sent, no name/CPF

Multiple Providers

# OpenAI
client_openai = EthIdClient(provider=LLMProvider.OPENAI)

# Claude
client_claude = EthIdClient(provider=LLMProvider.CLAUDE)

# Ollama (offline)
client_ollama = EthIdClient(
    provider=LLMProvider.OLLAMA,
    offline=True
)

Error Handling

from ethid import (
    DocumentParsingError,
    ClaimParsingError,
    VerificationError,
)

try:
    result = client.verify(
        document_path="document.pdf",
        claim="over 18 years old"
    )
except DocumentParsingError as e:
    print(f"Failed to parse document: {e}")
except ClaimParsingError as e:
    print(f"Failed to parse claim: {e}")
except VerificationError as e:
    print(f"Verification failed: {e}")

Requirements

  • Python 3.8+
  • ETH.id CLI installed (cargo install --path .)

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black ethid/

# Type check
mypy ethid/

License

MIT

Links

Metadata

Release files for ethid 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 ethid 0.1.0
File Size Uploaded Provenance
ethid-0.1.0.tar.gz 10.1 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 18.5 kB

Release files / ethid-0.1.0.tar.gz

Download URL ethid-0.1.0.tar.gz
Size 10.1 kB
Tags Source
SHA-256 checksum
How to use checksums
530206fb7777b2dbcc907ea15794235b576fc217dec04130abe4abf7add8570e
BLAKE2b-256 checksum
How to use checksums
d230254d6fcec27bca07886112ba78facc90582e9c35ce47b593d1f536d0f41d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.3

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

Download URL ethid-0.1.0-py3-none-any.whl
Size 8.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4117339a92a3912d73db90a90b77a19c50a70a76b764ded67812f49a4ad04a5
BLAKE2b-256 checksum
How to use checksums
9155af6442712e76ba85d32acf2e534c80959680bafdf4af1528dc9c455b0a22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.3

Security for ethid 0.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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