SDK Reference

Complete reference for the PhronEdge Python SDK.

Current version: 2.4.6

Installation

Shell
pip install phronedge

Requires Python 3.9 or higher. Works with any framework. No additional dependencies.

PhronEdge class

Python
from phronedge import PhronEdge

pe = PhronEdge(
    api_key=None,         # reads PHRONEDGE_API_KEY env var if not set
    gateway_url=None,     # reads PHRONEDGE_GATEWAY_URL or defaults to https://api.phronedge.com/api/v1
    timeout=30,           # request timeout in seconds
    raise_on_block=False, # if True, blocked calls raise ToolBlocked instead of returning a dict
    agent_id=None,        # agent ID to fetch credential for (one key, many agents)
)

Constructor parameters

ParameterTypeDefaultDescription
api_keystrNoneAPI key starting with pe_live_. If not set, reads from PHRONEDGE_API_KEY environment variable
gateway_urlstrNoneGateway URL. If not set, reads from PHRONEDGE_GATEWAY_URL or defaults to https://api.phronedge.com/api/v1
timeoutint30Request timeout in seconds for all gateway calls
raise_on_blockboolFalseWhen True, blocked tool calls raise ToolBlocked. When False, they return a dict with block details
agent_idstrNoneAgent ID to fetch credential for. Allows one API key to govern multiple agents under the same tenant

Environment variables

VariableDescription
PHRONEDGE_API_KEYYour API key. Required unless passed to constructor
PHRONEDGE_GATEWAY_URLGateway URL override. Useful for enterprise self-hosted and local development
PHRONEDGE_AGENT_IDDefault agent ID. Can be overridden by the constructor parameter

Multi-agent tenants

When one API key owns multiple agents, pass agent_id explicitly so the SDK fetches the right credential:

Python
pe_fraud = PhronEdge(agent_id="fraud-analyst")
pe_kyc   = PhronEdge(agent_id="kyc-verifier")

Without agent_id, the SDK fetches the first available credential. This is fine for single-agent tenants but unreliable with multiple agents.

govern() decorator

Python
@pe.govern(tool_name, action="execute", jurisdiction=None, mcp=None, delegates=None)
def my_tool(arg1, arg2):
    ...

Parameters

ParameterTypeDefaultDescription
tool_namestrrequiredMust match a tool ID in your signed policy
actionstr"execute"Permission level: read, write, delete, or execute
jurisdictionstrNoneISO alpha-2 country code. Gateway checks against the tool's allowed jurisdiction list
mcpstrNoneMCP server URL for tool discovery
delegateslistNoneAgent IDs this call can delegate to

Decorator order

When combining with framework decorators, PhronEdge must be the inner decorator:

Python
# LangGraph / LangChain
@tool
@pe.govern("my_tool", action="read")
def my_tool(): ...

# CrewAI
@tool("my_tool")
@pe.govern("my_tool", action="read")
def my_tool(): ...

# OpenAI Agents
@function_tool
@pe.govern("my_tool", action="read")
def my_tool(): ...

# LlamaIndex (no framework decorator needed)
@pe.govern("my_tool", action="read")
def my_tool(): ...

# Google ADK (no framework decorator needed)
@pe.govern("my_tool", action="read")
def my_tool(): ...

Behavior on block

raise_on_block=False (default)

The function body does not execute. A dict is returned:

Python
{
    "blocked": True,
    "reason": "Action 'delete' not permitted on tool 'claim_lookup'. Allowed: read, execute",
    "checkpoint": "judge",
    "regulation": "EU AI Act Art. 14",
    "retry": True,
    "message": "Tool call blocked by PhronEdge governance."
}

This is recommended for agentic frameworks where the LLM needs to see the block reason and adapt its next action.

raise_on_block=True

The function body does not execute. A ToolBlocked (or AgentTerminated) exception is raised:

Python
from phronedge import PhronEdge, GovernanceError, ToolBlocked, AgentTerminated

pe = PhronEdge(raise_on_block=True)

try:
    result = my_tool("arg")
except AgentTerminated as e:
    # Agent has been permanently killed. Not retryable.
    log_kill_event(e)
except ToolBlocked as e:
    print(e.reason)       # "Action 'delete' not permitted..."
    print(e.checkpoint)   # "judge"
    print(e.regulation)   # "EU AI Act Art. 14"
    print(e.retry)        # True
    print(e.blocked)      # True
except GovernanceError as e:
    # Base class. Catch infrastructure failures (gateway unreachable, invalid key).
    handle_infra_error(e)

Order except clauses from most specific to most general. AgentTerminated before ToolBlocked before GovernanceError.

Exception classes

ClassParentWhen raised
GovernanceErrorExceptionBase class. Infrastructure errors (gateway unreachable, invalid API key, 5xx).
ToolBlockedGovernanceErrorTool call blocked by a checkpoint. May be retried.
AgentTerminatedGovernanceErrorAgent has been permanently killed. Not retryable.

Common attributes

All three exception classes expose the same attribute set for consistent error handling:

AttributeTypeDescription
reasonstrHuman-readable reason for the block
checkpointstrWhich checkpoint blocked: credential_validator, jurisdiction, judge, tool_permission, pii_scanner, behavioral, output_filter
regulationstrRegulation that triggered the block (e.g. GDPR Art. 44-49, EU AI Act Art. 14)
retryboolWhether the call can be retried. False when the agent is quarantined or killed
blockedboolTrue when the tool was blocked by governance. False for pure infrastructure errors

All attributes are populated. Accessing any attribute on any exception will not raise AttributeError.

Utility methods

pe.scan(text)

Pre-scan text for PII or prompt injection before sending to an LLM. Useful for catching risky input before it hits a tool.

Python
result = pe.scan("Customer SSN is 123-45-6789")
# {
#   "patterns": ["SSN"],
#   "pii_detected": True,
#   "prompt_injection": False
# }

Returns an empty dict if the gateway is unreachable. Never raises.

pe.status()

Check gateway status and session activity.

Python
result = pe.status()
# {
#   "status": "operational",
#   "active_sessions": 2
# }
FieldDescription
statusoperational when the gateway is serving traffic
active_sessionsActive agent sessions in the last window

Additional implementation fields may appear. Only status and active_sessions are guaranteed.

Returns an {"error": ...} dict on failure. Never raises.

Agent lifecycle methods

The SDK can suspend and reinstate its own agent. This is useful for self-quarantine when the application detects anomalous behavior.

pe.quarantine(reason)

Suspend all tool access for the agent. All subsequent calls are blocked at the gateway. Reversible with pe.reinstate().

Python
pe.quarantine(reason="Anomalous behavior detected: 30 calls in 10 seconds")

Anchors AGENT_QUARANTINED event to the audit chain. Takes effect within one second.

pe.reinstate(reason)

Restore tool access for a quarantined agent. Has no effect on a killed agent.

Python
pe.reinstate(reason="Investigation complete. Behavior normalized.")

Anchors AGENT_REINSTATED event to the audit chain.

pe.kill()

The kill switch is not available through the SDK. Kill is permanent and irreversible, so it is restricted to the Console. Calling pe.kill() raises GovernanceError with a message directing you to the Console at phronedge.com/brain.

The 7 checkpoints

Every governed tool call passes through 7 checkpoints in the gateway. The function body does not execute until all 7 pass.

#CheckpointCommon block reasons
1Credential ValidatorExpired credential, invalid signature, revoked credential
2PII DetectorPersonal data in input triggers session elevation or block
3Jurisdiction RouterCall jurisdiction not in tool's allowed list
4Behavioral BaselineCall rate exceeds spike multiplier on baseline
5JudgeTool not in permitted_tools, action not in permissions, tier insufficient
6Data ClassifierResponse data class exceeds agent clearance
7Output ConstraintOutput redaction rule triggered

The checkpoint that blocked the call is available as e.checkpoint on the exception (or result["checkpoint"] in soft-block mode).

Credential caching

The SDK caches the credential for 5 minutes after the first fetch. This means the first call in a session makes one HTTP request to /auth/credential, and subsequent calls reuse the cached credential until it expires.

To force a fresh credential fetch:

Python
pe._credential = None
pe._credential_ts = 0

This is rarely needed. The credential auto-refreshes. Use this only when you know the credential has changed out-of-band (for example, immediately after a policy amendment from a different session).

Thread safety

One PhronEdge instance is safe to share across threads. The underlying requests.Session is thread-safe for read operations, and the credential cache is single-writer.

For async frameworks, the SDK uses synchronous HTTP calls via requests. For high-throughput async workloads, run the decorated function in a thread pool:

Python
import asyncio
result = await asyncio.to_thread(my_governed_tool, "arg")

Versioning

VersionNotes
2.4.6Current stable. Full exception attribute set (reason, blocked, retry, regulation, checkpoint). Soft-block returns dict, not JSON string.
2.4.xEnterprise signer and vault backends. Per-tenant key rotation.
2.3.xInitial multi-agent support.

Upgrade:

Shell
pip install --upgrade phronedge

Next steps

Previous
Quickstart
Next
Framework Guides