Python SDK
The klent-sdk PyPI package — synchronous client with background event batching.
pip install klent-sdkRequires Python ≥ 3.10. Single dependency: httpx.
Most apps want a higher-level entry point. This page documents the raw HTTP-shaped methods (
start_execution,evaluate_action,log_event). For day-to-day code, the auto-instrumentation helpers —run_tool,run_anthropic_agent— collapse the five-step boilerplate into a single call and run a complete Anthropic tool-use loop end-to-end. See Auto-instrumentation.
Instantiating the client
from klent_sdk import KlentClient
klent = KlentClient(api_key=os.environ["KLENT_API_KEY"])Arguments
| Argument | Default | Description |
|---|---|---|
api_key | required | A ak_live_… or ak_test_… key for a project. |
base_url | https://api.klent.dev/v1 | Override the API endpoint (e.g. a regional host). |
max_batch_size | 50 | Events buffered before a flush. |
flush_interval_seconds | 2.0 | Time window before flushing a partial batch. |
max_retries | 3 | Retries on 5xx and 429 with exponential backoff. |
timeout_seconds | 10.0 | Per-request HTTP timeout. |
http_client | None | Inject a pre-configured httpx.Client (e.g. with a custom proxy or CA bundle). |
Context manager
Prefer the context-manager form in short-lived scripts so buffered events flush cleanly:
with KlentClient(api_key=os.environ["KLENT_API_KEY"]) as klent:
execution = klent.start_execution({"agent_id": "billing-agent"})
...
# Events are flushed on __exit__.Methods
start_execution(body)
execution = klent.start_execution({
"agent_id": "support-agent",
"metadata": {"user_id": "u_123"},
})
# → Execution TypedDictevaluate_action(body)
decision = klent.evaluate_action({
"execution_id": execution["id"],
"tool": "send_email",
"input": {"to": "[email protected]", "subject": "Hi"},
})
if decision["decision"] == "deny":
raise RuntimeError(decision["reason"])log_event(body)
Non-blocking — buffered on a background queue.
klent.log_event({
"execution_id": execution["id"],
"type": "action_executed",
"payload": {"tool": "send_email"},
})get_pending_action(pending_action_id, *, wait_ms=0)
Fetch the current state of a pending action — the row created when an approve policy
parks an action for human review. Returns a typed dict with status (pending,
approved, rejected) plus, on terminal states, reviewer note and any last-mile
modifications.
row = klent.get_pending_action("pact_…")
if row["status"] == "pending":
# still waiting on a human
...wait_ms opts into a server-side long-poll: the request stays open until the row
resolves or the budget elapses (server caps each call at 30 000 ms; run_tool's
approval_wait chains long-polls under the hood for longer budgets).
row = klent.get_pending_action("pact_…", wait_ms=30_000)Most apps don't call this directly — run_tool(... approval_wait={"timeout_seconds": 600}) in Auto-instrumentation wraps it. Use the raw
method when you're polling from a different process (e.g. a worker that resumes paused
executions).
flush()
Force-flush the buffer. Called automatically via atexit and on context-manager exit.
klent.flush()close()
Flush and close the underlying HTTP client. Also called by __exit__.
klent.close()Thread safety
EventBuffer is thread-safe under concurrent log_event calls and serializes flushes via
an inner lock. You can share a single KlentClient across threads without wrapping.
Error handling
Methods raise:
ValueError— missingapi_key.RuntimeError— a 4xx from the API (not retried) or exhausted retries on 5xx/429.httpx.HTTPErrorsubclasses only if you setmax_retries=0and the underlying network call fails.
The message includes the HTTP status and the response body so you can diagnose without reaching for a debugger.
Types
TypedDicts live in klent_sdk.types:
from klent_sdk.types import (
CreateExecutionRequest,
EvaluateActionRequest,
EvaluateActionResponse,
Event,
EventType,
Execution,
LogEventRequest,
PolicyEffect,
)They match the TypeScript SDK types field-for-field.