Skip to main content

Python SDK for the Polaxis AI Agent Governance Platform

Project description

Polaxis SDK

Python SDK and MCP server for the Polaxis AI Agent Governance Platform.

Polaxis sits between your AI agent and its tools, evaluating every tool call against your policies in real time — blocking dangerous actions, enforcing spend limits, and routing ambiguous calls to a human approver — all in under 5ms.

PyPI version Python License: MIT Tests


What does Polaxis do?

Your AI agent
    │
    │  tool_call("delete_records", {"table": "users"})
    ▼
┌─────────────────────────────────────────┐
│          Polaxis Policy Engine          │
│  • Evaluate against your policy rules   │
│  • Check agent spend budget             │
│  • Scan for prompt injection / PII      │
│  • Route to human approver if needed    │
└─────────────────────────────────────────┘
    │
    │  decision: "allow" | "block" | "escalate"
    ▼
Your tools (database, email, API…)

Three possible outcomes for every tool call:

Decision Meaning What to do
allow Call is within policy. Proceed. Execute the tool
block Call violates a rule or budget. Abort — log the reason
escalate Human sign-off required. Wait for approval via Slack or dashboard

Installation

pip install polaxis

With MCP server support:

pip install "polaxis[mcp]"

Requirements: Python 3.10+


Quick start

1. Get your API key — create a free account at polaxis.io, add an agent, and copy its API key.

2. Set the environment variable:

export POLAXIS_API_KEY=ag_prod_...

3. Evaluate every tool call before executing it:

import asyncio
from polaxis import Polaxis, PolicyBlockError

guard = Polaxis()  # reads POLAXIS_API_KEY from env

async def send_invoice(customer_id: str, amount: float):
    # ← Evaluate BEFORE touching any tool
    result = await guard.evaluate(
        tool_name="send_invoice",
        tool_input={"customer_id": customer_id, "amount_usd": amount},
        session_id="session-001",
    )

    # result.decision is "allow", "block", or "escalate"
    if result.allowed:
        your_invoice_api.send(customer_id, amount)

asyncio.run(send_invoice("cust_123", 499.00))

That's it. Every call is now governed, logged, and auditable from your Polaxis dashboard.


API reference

Polaxis(api_key, *, base_url, timeout, raise_on_block, raise_on_budget)

Main async client. Create one instance per agent and reuse it.

Parameter Type Default Description
api_key str env POLAXIS_API_KEY Your agent API key
base_url str https://api.polaxis.io Override for self-hosted
timeout float 10.0 HTTP request timeout (seconds)
raise_on_block bool True Raise PolicyBlockError / FirewallBlockError instead of returning a blocked result
raise_on_budget bool True Raise BudgetExceededError on budget violations

await guard.evaluate(tool_name, tool_input, *, session_id, estimated_cost_usd)

Evaluate a proposed tool call. Call this before every tool execution.

result = await guard.evaluate(
    tool_name="send_email",
    tool_input={"to": "alice@example.com", "subject": "Hello"},
    session_id="sess_abc",         # optional — groups calls in audit logs
    estimated_cost_usd=0.002,      # optional — for budget tracking
)

Returns EvaluateResult.

Raises:

  • PolicyBlockError — blocked by a policy rule
  • FirewallBlockError — blocked by the Agent Firewall (prompt injection, PII, secrets)
  • BudgetExceededError — agent's budget is exhausted
  • AuthenticationError — bad API key
  • APIError — unexpected HTTP error

await guard.await_approval(approval_id, *, timeout_seconds, poll_interval)

Poll until a human approver acts on an escalated request.

result = await guard.evaluate("wire_transfer", {"amount": 50_000})

if result.pending_approval:
    status = await guard.await_approval(
        result.approval_id,
        timeout_seconds=result.timeout_seconds,
    )
    if status.approved:
        execute_transfer()

Raises:

  • ApprovalRejectedError — approver clicked Reject
  • ApprovalTimeoutError — no decision within timeout_seconds

EvaluateResult

Attribute Type Description
decision str "allow" | "block" | "escalate"
allowed bool Shorthand for decision == "allow"
blocked bool Shorthand for decision == "block"
pending_approval bool Shorthand for decision == "escalate"
reason str | None Human-readable explanation
policy_triggered str | None Policy name that matched
rule_name str | None Specific rule that matched
approval_id str | None For escalated calls — pass to await_approval()
timeout_seconds int How long to wait for approval
budget_remaining_usd float Remaining daily budget
budget_warning bool Budget is below 20%
threats list Detected firewall threats (non-blocking)

PolaxisSync — synchronous usage

For scripts and non-async frameworks:

from polaxis import PolaxisSync

guard = PolaxisSync()
result = guard.evaluate("delete_records", {"table": "orders", "where": "status='test'"})

if result.blocked:
    raise RuntimeError(f"Blocked: {result.reason}")

Error handling

All exceptions inherit from PolaxisError:

from polaxis import (
    PolicyBlockError,      # policy rule matched → block
    FirewallBlockError,    # firewall detected threat
    BudgetExceededError,   # daily/monthly budget hit
    ApprovalRejectedError, # human said no
    ApprovalTimeoutError,  # no decision in time
    AuthenticationError,   # bad API key
    APIError,              # HTTP error
)

Pattern — handle without raising:

guard = Polaxis(raise_on_block=False, raise_on_budget=False)
result = await guard.evaluate("tool", input)

match result.decision:
    case "allow":
        run_tool()
    case "block":
        log.warning("Blocked: %s", result.reason)
    case "escalate":
        status = await guard.await_approval(result.approval_id)

Human-in-the-loop (HITL)

When a policy rule has action require_approval, Polaxis pauses the agent and sends an approval request to your configured Slack channel or dashboard.

result = await guard.evaluate("deploy_to_production", {"service": "api", "version": "v2.1.0"})

if result.pending_approval:
    print(f"Waiting for approval (id: {result.approval_id})")
    # This blocks (async) until approved, rejected, or timed out
    status = await guard.await_approval(
        result.approval_id,
        timeout_seconds=600,   # 10 minute window
    )
    if status.approved:
        deploy()
    # ApprovalRejectedError or ApprovalTimeoutError raised otherwise

Your team sees this in Slack:

🔔 Polaxis — Approval Required
Agent: deploy-bot  |  Policy: prod-deploy-policy
Tool: deploy_to_production
Input: {"service": "api", "version": "v2.1.0"}

[✓ Approve]  [✗ Reject]

Framework integrations

OpenAI function calling

# See examples/openai_tools_example.py for the full pattern
async def execute_tool(tool_name: str, tool_input: dict) -> str:
    result = await guard.evaluate(tool_name, tool_input)
    if result.allowed:
        return your_tool_implementations[tool_name](**tool_input)
    return f"Blocked: {result.reason}"

LangChain

# See examples/langchain_example.py for a GovernedTool base class
class MyTool(GovernedTool):
    name = "my_tool"

    async def _run_governed(self, **kwargs):
        # Only called when Polaxis says "allow"
        return do_the_work(**kwargs)

MCP (Model Context Protocol)

Add the Polaxis governance proxy to your MCP client config:

{
  "mcpServers": {
    "polaxis-proxy": {
      "command": "python",
      "args": ["-m", "polaxis_mcp.server"],
      "env": {
        "POLAXIS_API_KEY": "ag_prod_..."
      }
    }
  }
}

The server exposes a polaxis_evaluate tool your agent calls before any action. See examples/mcp_config.json for a full config example.

CrewAI / PydanticAI / AutoGen

The pattern is the same for any framework — evaluate before calling the tool, handle the three outcomes. See the examples/ directory.


Policy examples

Policies are configured in the Polaxis dashboard (JSON format). Here are common patterns:

Block large financial transactions:

{
  "name": "finance-guard",
  "rules": [
    {
      "trigger": { "tool": "charge_card", "condition": "amount_usd > 500" },
      "action": "block",
      "message": "Charges over $500 require manual processing."
    }
  ]
}

Require approval for production deployments:

{
  "name": "prod-deploy",
  "rules": [
    {
      "trigger": { "tool": "deploy", "condition": "environment == 'production'" },
      "action": "require_approval",
      "message": "Production deploys require engineering lead sign-off."
    }
  ]
}

Rate-limit a noisy tool:

{
  "name": "api-rate-limit",
  "rules": [
    {
      "trigger": { "tool": "call_external_api", "condition": "rate_per_hour > 100" },
      "action": "block",
      "message": "External API rate limit exceeded."
    }
  ]
}

Examples

File What it shows
examples/basic_usage.py Core evaluate + HITL pattern
examples/openai_tools_example.py OpenAI function-calling agent loop
examples/langchain_example.py LangChain GovernedTool base class
examples/mcp_config.json MCP client config for the proxy server

Self-hosted deployment

On Pro and Enterprise plans you can run the full Polaxis stack in your own infrastructure:

# Clone the platform
git clone https://github.com/polaxis-io/polaxis-sdk.git

# Full Docker Compose stack
docker compose up

Point the SDK at your instance:

guard = Polaxis(
    api_key="ag_prod_...",
    base_url="https://polaxis.your-company.com",
)

Contributing

Contributions are welcome! See CONTRIBUTING.md for:

  • Development setup
  • How to add a new framework integration
  • Running tests
  • PR checklist and design principles

Support

Channel Link
Documentation docs.polaxis.io
Dashboard polaxis.io
GitHub Issues github.com/polaxis-io/polaxis-sdk/issues
Email sdk@polaxis.io

License

MIT — see LICENSE.

Project details


Download files

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

Source Distribution

polaxis-0.1.0.tar.gz (20.0 kB view details)

Uploaded Source

Built Distribution

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

polaxis-0.1.0-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

File details

Details for the file polaxis-0.1.0.tar.gz.

File metadata

  • Download URL: polaxis-0.1.0.tar.gz
  • Upload date:
  • Size: 20.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for polaxis-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b14fdf18e7f03741e4f6e533f3eaafa57abdde07d5aa4d2b18005024273f4c10
MD5 46f29131f99ea2b937a77d9fc07da1fd
BLAKE2b-256 0dff26b8a3f671ae6581fb9b865c8e7dbd26c1bf71df0edb7b8f0d609ee2912c

See more details on using hashes here.

File details

Details for the file polaxis-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: polaxis-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for polaxis-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 590b696dd9d03618080684a686d19e73dbf5aead074b359448b0ff79e68cffc5
MD5 b3177f731aa5d308bf146752125d80e9
BLAKE2b-256 f51452f1fde2a75eb9b847c8f46817f2727fb5e119c6cc085d1d596d2b8e1cd2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page