Skip to main content

Quesen Python SDK

Official typed Python client for Quesen — the deterministic A2A risk-evaluation API.

Status: v0.3.0 · tracks Quesen engine v1.10.0 (+ TSC v2 agent firewall) · backward compatible with v1.0.0+ deployments. Developer portal: senueren.co.za/quesen — canonical docs, API reference, and integration guides. This SDK is a thin HTTP client; the hosted engine is served at https://web-production-aa5ba.up.railway.app.


Install

pip install quesen-sdk

Python 3.9+, single runtime dependency (httpx).


30-second usage

from quesen_sdk import QuesenClient

client = QuesenClient(
    base_url="https://<your-quesen-endpoint>",
    api_key="sk_live_abc",  # optional if the deployment is in open mode
)

result = client.validate(
    domain_age_days=1,
    engagement_ratio=0.95,
    scam_keyword_count=4,
)

print(result.decision)              # 'SKIP'
print(result.risk_score)            # 1.0
print(result.conflict_triggers)     # ['New domain (<=30d) + unusually high engagement (>=0.50)', ...]
print(result.request_id)            # UUID — pass to client.report() later
print(result.input_snapshot_hash)   # 64-char SHA-256 hex — self-contained replay primitive (v1.10+)
print(result.commit_sha)            # 40-char git SHA of the engine ruleset that produced the verdict (v1.10+)

Agent Firewall (TSC v2) — one call before any high-risk action

TSC v2 turns Quesen into a deterministic agent firewall: describe what your autonomous agent is about to do and get a PASS / REVIEW / BLOCK / SKIP verdict plus a tamper-evident audit receipt — before the action crosses a trust boundary. Secret/credential egress to an untrusted destination is deterministically blocked; suspected prompt injection is sent to review; unauthorized privilege grants are refused.

Requires an engine running with QUESEN_TSC_V2_ENABLED=true (route POST /tsc/validate).

from quesen_sdk import QuesenClient
from quesen_sdk.tsc import TscContext, TscBlocked

client = QuesenClient(base_url="https://<your-quesen-endpoint>", api_key="sk_live_abc")

# Your agent is about to POST data somewhere. Ask Quesen first.
decision = client.validate_tsc(
    TscContext.data_egress(
        data_classes=["secret"],          # what's leaving
        to="https://paste.evil.example",  # where it's going
        destination_trust="unverified",
        framework="langchain",
    )
)

print(decision.decision)       # 'BLOCK'
print(decision.reason_codes)   # ['EGRESS_SECRET_UNTRUSTED']
print(decision.tags)           # ['exfiltration']
print(decision.commit_sha, decision.input_snapshot_hash)  # audit receipt

# Fail-closed gate: raise unless the engine explicitly returned PASS.
try:
    decision.require_pass()
    run_the_tool()             # only reached on PASS
except TscBlocked as e:
    log_and_stop(e.decision)   # BLOCK / REVIEW / SKIP never runs the tool

Scenario builders cover the common catastrophic actions:

Builder Agent is about to…
TscContext.data_egress(...) send data OUT (exfiltration / PII / secret leakage)
TscContext.tool_call(...) invoke a tool/capability (privilege + injection checks)
TscContext.payment(...) move money / perform a financial action

You can also pass a plain dict (or anything with .to_dict()) to client.validate_tsc(...) for full control of the Typed Security Context schema.

Runnable demos: examples/agent_firewall.py (pure SDK) and examples/langchain_firewall.py (LangChain tool wrapper).

Async is symmetric — await AsyncQuesenClient(...).validate_tsc(ctx).

Receipt provenance (v1.10, tracked in SDK v0.2.0)

Every ValidateResult and SimulateResult.baseline / .simulated now carries two additional fields that make the verdict self-contained-replayable:

  • input_snapshot_hash · lowercase 64-char SHA-256 hex over canonical-JSON of the received request payload, with client_request_id excluded from the hash material. Hash the same payload client-side and prove the engine evaluated the exact input you sent.
  • commit_sha · 40-char lowercase git SHA of Shxnque/quesen HEAD live at build time, or the sentinel "unknown" when running detached HEAD or a locally-built artifact. Pins the exact ruleset that produced the verdict.

Client-side hash reconstruction

import hashlib, json

def input_snapshot_hash(payload: dict) -> str:
    to_hash = {k: v for k, v in payload.items()
               if v is not None and k != "client_request_id"}
    canonical = json.dumps(to_hash, sort_keys=True, separators=(",", ":"),
                           ensure_ascii=False, allow_nan=False).encode("utf-8")
    return hashlib.sha256(canonical).hexdigest()

assert result.input_snapshot_hash == input_snapshot_hash({
    "domain_age_days": 1,
    "engagement_ratio": 0.95,
    "scam_keyword_count": 4,
})

Replay recipe

git clone https://github.com/Shxnque/quesen && cd quesen
git checkout $COMMIT_SHA
pytest tests -q       # asserts engine state at decision time
# Re-issue the request; verify input_snapshot_hash matches.

Backward compatibility. Against a pre-v1.10 engine the two fields default to the empty string. Callers who upgrade the SDK against an older engine continue to work unchanged; callers who upgrade the engine start seeing non-empty values automatically.


Async usage

import asyncio
from quesen_sdk import AsyncQuesenClient

async def main() -> None:
    async with AsyncQuesenClient(base_url="https://q.example.com", api_key="sk_live_abc") as q:
        decision = await q.validate(domain_age_days=200, engagement_ratio=0.3)
        if decision.decision == "SKIP":
            return  # don't act
        # ... execute the action ...
        await q.report(request_id=decision.request_id, outcome="OK", realized_pnl=0.42)

asyncio.run(main())

What the client gives you

  • Typed request + response models (dataclass-like, __slots__, IDE-friendly attrs).
  • Automatic retries with exponential back-off on 5xx / network errors.
  • request_id propagation — the UUID emitted by /validate is what you pass to /report.
  • X-Request-ID header — set once, echoed everywhere, useful for tracing across your stack.
  • /simulate helper for the free counterfactual sales asset.
  • Receipt provenance surfaced as typed fieldsinput_snapshot_hash + commit_sha are first-class attributes on ValidateResult (v0.2.0+).
  • Fail-closed policy — timeouts / network errors surface as QuesenTimeout and QuesenTransportError so the caller can decide (recommendation: treat as SKIP).
  • Zero heavy dependencies — just httpx.

API surface

Sync client: QuesenClient(base_url, api_key=None, timeout=5.0, retries=2, retry_backoff=0.2, request_id_header="X-Request-ID", user_agent="quesen-sdk-py/0.2.0")

Method Wraps Purpose
client.health() GET /health Liveness.
client.version() GET /version Engine + weights + thresholds.
client.validate(...) POST /validate Deterministic decision. Response carries input_snapshot_hash + commit_sha against v1.10+ engines.
client.simulate(...) POST /simulate Counterfactual with weights_override / thresholds_override.
client.report(...) POST /report Post-decision outcome feedback. v1.1.0 optional fields supported.

Async client: AsyncQuesenClient(...) mirrors the sync surface with async def methods.


Error hierarchy

QuesenError
├── QuesenAuthError        # 401 — invalid or missing X-API-Key
├── QuesenRateLimitError   # 429 — per-key quota exceeded, Retry-After surfaced
├── QuesenValidationError  # 422 — pydantic-side reject
├── QuesenServerError      # 5xx after retries exhausted
├── QuesenTimeout          # transport timeout
└── QuesenTransportError   # generic transport failure

Environment variables

Var Meaning
QUESEN_BASE_URL Optional default base URL if not passed to the client constructor.
QUESEN_API_KEY Optional default API key if not passed to the client constructor.

Doctrine compliance

This SDK preserves Quesen doctrine end-to-end:

  • Determinism. The SDK does not add ML, prompts, randomness, or state. Same input in → same input out.
  • Ecosystem neutrality. No chain lock-in, no framework lock-in, no LLM lock-in. httpx only.
  • Fail-closed. Timeouts and network errors surface as exceptions. Callers should treat them as SKIP.
  • Request-ID propagation. Every call sets X-Request-ID so your /report calls are correlatable to the original /validate.
  • Receipt provenance forwarded. input_snapshot_hash + commit_sha are exposed as typed fields (v0.2.0+), enabling client-side replay-verification and ruleset-pin discipline.

License

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quesen_sdk-0.4.0.tar.gz (23.7 kB view details)

Uploaded Source

Built Distribution

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

quesen_sdk-0.4.0-py3-none-any.whl (18.4 kB view details)

Uploaded Python 3

File details

Details for the file quesen_sdk-0.4.0.tar.gz.

File metadata

  • Download URL: quesen_sdk-0.4.0.tar.gz
  • Upload date:
  • Size: 23.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for quesen_sdk-0.4.0.tar.gz
Algorithm Hash digest
SHA256 bb6a09eb67b0f0e33c00b4ffae4a64152bc44e56029266871fa277016931ff4e
MD5 9dad171df1a499f3d28e99ddcb761b9f
BLAKE2b-256 ab75867fed3456d9dcf59ced6b1b42b10d78b537e9c25c944614c6689733e03d

See more details on using hashes here.

File details

Details for the file quesen_sdk-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: quesen_sdk-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 18.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for quesen_sdk-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5f6fd4993245f04bf1b5c96ef55e1c064c87782e7ab3a886ab334cc9b13a1310
MD5 f35e2ad65c7a81865d8ce31c3820937a
BLAKE2b-256 fa44db27a051d793478ad7144ff94d61d649f12a5a59de517d85259852063127

See more details on using hashes here.

Release history Release notifications | RSS feed

0.4.1

2 files

This release

0.4.0 This release

2 files

0.3.0

2 files

0.2.0

2 files

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