Skip to main content

Zero-Knowledge Document Verification SDK for Python

Project description

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

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

ethid-0.1.0.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

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

ethid-0.1.0-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file ethid-0.1.0.tar.gz.

File metadata

  • Download URL: ethid-0.1.0.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for ethid-0.1.0.tar.gz
Algorithm Hash digest
SHA256 530206fb7777b2dbcc907ea15794235b576fc217dec04130abe4abf7add8570e
MD5 96441d4001d08f88200e12f52aeed3a0
BLAKE2b-256 d230254d6fcec27bca07886112ba78facc90582e9c35ce47b593d1f536d0f41d

See more details on using hashes here.

File details

Details for the file ethid-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ethid-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for ethid-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a4117339a92a3912d73db90a90b77a19c50a70a76b764ded67812f49a4ad04a5
MD5 75bb5eab5c5de525c7f678e6e4057155
BLAKE2b-256 9155af6442712e76ba85d32acf2e534c80959680bafdf4af1528dc9c455b0a22

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