The patterns on this page (retry decorators, an audit-log schema, a rate
limiter) are illustrative — adapt them to your own stack. What’s specific to
Parmana (the client construction, the exception taxonomy, which call raises
what) is the real, verified API — see Python SDK. For how to
actually run the server itself in production (Fly.io, Docker, environment
variables the server reads), see Production
deployment and Deploy
patterns — this page is about the client side,
calling an already-deployed Parmana instance.
Deployment shape
Configuration
ParmanaConfig object to pass around — ParmanaClient takes endpoint and api_key
directly. Keep your own settings object (like ParmanaSettings above) if you want centralized
validation; just unpack it into the two real constructor kwargs.
Error handling
Fail-closed by default
A denial should be a denial, not an exception a caller has to remember to interpret correctly. Wrap the client so every failure mode — policy rejection, network error, timeout — resolves to “did not execute”, explicitly:Error types
The exception taxonomy is real and verified — see Errors, correctly mapped to real conditions for the complete, tested table. The ones worth handling explicitly in production:Retries
ParmanaClient already retries idempotent GETs with backoff on 502/503/504; POSTs (which
execute() is) are never retried automatically, since retrying an execution isn’t safe by
default. If you want your own retry around a ServerError, keep it narrowly scoped to that one
exception and make sure you’re supplying your own business_transaction_id so a retried request
is idempotent server-side rather than creating a second transaction:
Audit logging
Parmana already produces a signed Execution Trust Record for every approved execution, and a Refusal Record for a rejected one — both independently verifiable. What you typically still want on your own side is a queryable local log tying those records back to your application’s own request context:Monitoring
Track outcomes and latency around everyexecute() call, however your stack already does
metrics (Prometheus shown here as one example):
NetworkError/ServerError rate
above zero for more than a few minutes, and p99 latency past whatever your own SLA is.
Rate limiting
If you’re calling Parmana from a high-throughput path and want to shed load client-side rather than let the server’s own limits reject you:Smoke-testing a deployment
Run something like this after every deploy — it should complete without raising anything other than an expectedExecutionRejectedError:
Deployment checklist
-
PARMANA_ENDPOINTandPARMANA_API_KEY(or equivalent) set from your secrets manager, not hardcoded - Fail-closed behavior confirmed for
NetworkError/ServerError(see above) -
ExecutionRejectedErrorhandled as an expected, logged outcome — not swallowed silently - Your own audit log wired up, keyed by
business_transaction_id - Basic metrics (outcome counts, latency) exported
- Smoke test run against the target environment after deploy
- You’ve read Limitations — know what Parmana does and doesn’t guarantee before you make claims of your own downstream
Next
Production deployment
Running the Parmana server itself in production — the other half of this
page.
Python SDK for AI Agents
The integration patterns this guide’s error handling wraps around.
Limitations
What Parmana does and doesn’t guarantee — read before you write your own SLA
on top of it.
Python SDK reference
The complete, verified API surface: every method, every error, the test
suite backing it.