Skip to content
Developer previewBack to Kernall
Browse documentation
DocumentationIntegrations

Integrations

Python SDK

Use the dependency-free source client to check actions and wait for human decisions.

Use the source client

The client lives in sdk/python/kernall and uses Python’s standard library. No PyPI installation is documented or verified. Use Python 3 with that directory on its import path.

Save the example below as your_agent.py at the repository root, then run:

Run with the repository SDK
# From the repository root:
export KERNALL_BASE_URL="http://localhost:3000"
export KERNALL_API_KEY="paste-your-real-project-key"
PYTHONPATH="$PWD/sdk/python" python3 your_agent.py

Use a real key from the quickstart and keep the API server running separately.

Check and wait safely

your_agent.py
import os
from kernall import Kernall, KernallError, KernallTimeoutError

gate = Kernall(
    api_key=os.environ["KERNALL_API_KEY"],
    base_url=os.environ.get("KERNALL_BASE_URL", "http://localhost:3000"),
    timeout=10.0,
)

def may_proceed(action, data, destination, step_id):
    try:
        result = gate.check(
            action=action,
            data=data,
            destination=destination,
            task="Review a proposed form submission",
            idempotency_key=step_id,
        )
        if result.approved:
            return True
        if result.denied:
            print("Denied:", result.reason)
            return False
        if result.requires_human:
            print("Waiting for review:", result.confirmation_id)
            final = gate.wait_for_confirmation(
                result, timeout=300, poll_interval=2
            )
            return final.approved
        return False
    except (KernallTimeoutError, KernallError, TimeoutError) as error:
        print("Action remains blocked:", error)
        return False

if may_proceed(
    action="submit",
    data="Sample form content",
    destination="https://example.com/form",
    step_id="demo-form-submission-1",
):
    print("Approved. Your application may now execute this exact action.")
    # Call your actual tool here, and make that operation idempotent too.

This example prints an approval message and marks where your tool call belongs. An owner must resolve the review through the approval API. The script does not submit a form or approve itself.

Client methods

MethodParameters and behavior
Kernall(api_key, base_url, timeout)Key required. Base URL defaults to http://localhost:3000; request timeout defaults to 10 seconds.
check(action, data, destination, task, idempotency_key=…)Maps action to action_type and task to task_context. Returns CheckResult. Generates a UUID if no idempotency key is given.
confirmation_status(confirmation)Accepts a confirmation ID or a CheckResult containing one. Checks once.
wait_for_confirmation(confirmation, timeout=300, poll_interval=2)Polls synchronously until resolved or timed out. Both numeric values must be positive.

Results and exceptions

CheckResult exposes decision, reason, check_id, confirmation_id, confirmation_url, data_type_detected, and idempotent_replay, plus approved, denied, and requires_human booleans.

ConfirmationResult exposes confirmation_id, status, decision, and resolved_at, plus pending, approved, and denied booleans.

KernallError reports HTTP, connection, and response errors; HTTP errors include status_code. KernallTimeoutError means review polling timed out. Transport timeouts can also surface as Python timeout exceptions. Invalid local arguments can raise ValueError.

Retries and runtime behavior

The SDK blocks while polling. Use a worker thread or appropriate task runner when your application must remain responsive. It does not automatically retry HTTP failures or expose rate-limit response headers.

Retry with the original idempotency_key; omitting it creates a new check. The wait deadline does not cancel the server review. An in-flight request can continue until its separate request timeout.