🐍 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

MethodReturnsDescription
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):

  1. X-Soulprint-Token header
  2. Authorization: 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_did
  • request.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.

Source Code

github.com/manuelariasfz/soulprint/packages/python ↗