🐍 Python SDK
Verify human identity and Colombian cédulas from any Python app — async client, FastAPI & Django middleware included.
Installation
pip install soulprint-py
With FastAPI extras:
pip install "soulprint-py[fastapi]"
Requires Python 3.9+ and
httpx for async HTTP.
Quick Start
import asyncio
from soulprint import SoulprintClient
client = SoulprintClient(
node_url="https://soulprint-node-production.up.railway.app"
)
async def main():
# Verify a DID
result = await client.verify("did:soulprint:0xabc...")
print(f"Human: {result.is_human} Score: {result.score}/100")
# Verify a Colombian cédula against Registraduría
cedula = await client.verify_cedula("1234567890", "1990-01-15")
print(f"Vigente: {cedula.vigente}")
# Network stats
stats = await client.network_stats()
print(f"Active nodes: {stats.active_nodes}")
asyncio.run(main())
SoulprintClient Reference
Constructor
client = SoulprintClient(
node_url: str = "https://soulprint-node-production.up.railway.app",
timeout: float = 10.0, # seconds
)
Methods
| Method | Returns | Description |
|---|---|---|
verify(did) |
VerifyResult |
Check if a DID belongs to a verified human |
verify_cedula(numero, fecha_nac) |
CedulaResult |
Check cédula against Registraduría Nacional (Colombia) |
network_stats() |
NetworkStats |
Live stats: active nodes, verified identities, MCPs |
info() |
NodeInfo |
Node version, network, contracts, capabilities |
Return types
# VerifyResult
result.is_human: bool
result.score: int # 0–100
result.node_did: str
result.verified_at: datetime
# CedulaResult
result.vigente: bool
result.status: str # "VIGENTE" | "NO VIGENTE" | "ERROR"
result.numero: str
# NetworkStats
stats.active_nodes: int
stats.verified_identities: int
stats.verified_mcps: int
# NodeInfo
info.version: str
info.node_did: str
info.network: str # "base-sepolia"
info.capabilities: list[str]
FastAPI Middleware
from fastapi import FastAPI, Request
from soulprint.fastapi import require_human
app = FastAPI()
@app.post("/api/sensitive")
@require_human(
min_score=80,
node_url="https://soulprint-node-production.up.railway.app"
)
async def sensitive_endpoint(request: Request):
did = request.state.soulprint_did
score = request.state.soulprint_score
return {"did": did, "score": score}
Token read from (in order):
X-Soulprint-TokenheaderAuthorization: Bearer <token>header
Django Middleware
# settings.py
MIDDLEWARE = [
...
"soulprint.django.SoulprintMiddleware",
]
SOULPRINT_NODE_URL = "https://soulprint-node-production.up.railway.app"
SOULPRINT_MIN_SCORE = 50
SOULPRINT_EXEMPT_PATHS = ["/health", "/"]
Verified attributes on request:
request.soulprint_didrequest.soulprint_score
Error Handling
from soulprint.exceptions import (
SoulprintError,
NodeUnavailableError,
UnauthorizedError,
VerificationError,
)
try:
result = await client.verify("did:soulprint:0x...")
except NodeUnavailableError as e:
print(f"Node down: {e.node_url}")
except SoulprintError as e:
print(f"Error: {e}")
Verify cédula colombiana
cedula = await client.verify_cedula(
numero="1234567890",
fecha_nac="1990-01-15" # YYYY-MM-DD
)
if cedula.vigente:
print("✅ Cédula vigente — identidad confirmada")
else:
print("❌ Cédula no vigente o no encontrada")
Graceful degradation: si la Registraduría no responde, el validador retorna
vigente=false, status="ERROR" sin bloquear. Maneja este caso en tu app.