VerdifaX

AsyncVerdifaxClient

Async-native variant for FastAPI, asyncio workers, and any high-throughput inference server. Same surface as VerdifaxClient, methods return awaitables.

Import

from verdifax import AsyncVerdifaxClient

Constructor

AsyncVerdifaxClient(
    base_url: str | None = None,
    api_key: str | None = None,
    timeout: float = 30.0,
    transport: httpx.AsyncBaseTransport | None = None,
)

Same arguments as the sync client. Wraps httpx.AsyncClient instead.

Methods

await client.health() -> dict
await client.attest(...) -> AttestationReceipt
await client.verify(...) -> bool
await client.execute(...) -> ExecutionManifest
await client.close() -> None

Async context manager

async with AsyncVerdifaxClient() as client:
    receipt = await client.attest(
        payload="hello verdifax",
        program_id="a" * 64,
        route_id="route-test",
        registry_record_hash="b" * 64,
    )
    print(receipt.manifest_hash)

The connection pool closes automatically on exit.

FastAPI example

from contextlib import asynccontextmanager
from fastapi import FastAPI
from verdifax import AsyncVerdifaxClient

@asynccontextmanager
async def lifespan(app: FastAPI):
    app.state.verdifax = AsyncVerdifaxClient()
    yield
    await app.state.verdifax.close()

app = FastAPI(lifespan=lifespan)

@app.post("/inference")
async def inference(prompt: str):
    output = await call_my_model(prompt)
    receipt = await app.state.verdifax.attest(
        payload=f"prompt:{prompt}\nresponse:{output}",
        program_id="a" * 64,
        route_id="prod-inference",
        registry_record_hash="b" * 64,
    )
    return {"output": output, "manifest_hash": receipt.manifest_hash}

Concurrency

Many in-flight calls share one client safely — httpx.AsyncClient is concurrency-safe. Don't construct a new client per request.

Continue