Metadata-Version: 2.4
Name: axiorank
Version: 0.13.0
Summary: Official Python SDK for AxioRank. Zero-Trust for AI agents: route every tool call through one governed control plane.
Project-URL: Homepage, https://axiorank.com
Project-URL: Documentation, https://app.axiorank.com/docs
Project-URL: Source, https://github.com/frostyhand/AxioRank
Project-URL: Issues, https://github.com/frostyhand/AxioRank/issues
Author: AxioRank
License: MIT
License-File: LICENSE
Keywords: agent,agent-security,ai,axiorank,firewall,gateway,guardrails,llm,mcp,security,zero-trust
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.27
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.40; extra == 'anthropic'
Provides-Extra: crewai
Requires-Dist: crewai>=0.100; extra == 'crewai'
Provides-Extra: dev
Requires-Dist: cryptography>=42; extra == 'dev'
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: google-genai
Requires-Dist: google-genai>=1.0; extra == 'google-genai'
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.3; extra == 'langchain'
Provides-Extra: litellm
Requires-Dist: litellm>=1.60; extra == 'litellm'
Provides-Extra: llamaindex
Requires-Dist: llama-index-core>=0.10; extra == 'llamaindex'
Provides-Extra: openai-agents
Requires-Dist: openai-agents>=0.1; extra == 'openai-agents'
Provides-Extra: pydantic-ai
Requires-Dist: pydantic-ai>=1.0; extra == 'pydantic-ai'
Provides-Extra: smolagents
Requires-Dist: smolagents>=1.0; extra == 'smolagents'
Provides-Extra: verify
Requires-Dist: cryptography>=42; extra == 'verify'
Description-Content-Type: text/markdown

# axiorank

Catch leaked secrets, prompt injection, destructive commands, and PII in your AI
agent's tool calls. This runs the same detection engine the hosted
[AxioRank](https://axiorank.com) gateway runs, in-process, with no API key and no
signup.

Parity with the TypeScript [`@axiorank/sdk`](https://www.npmjs.com/package/@axiorank/sdk).

## Install

```bash
pip install axiorank
```

## Try it first (no API key)

See what AxioRank catches before you sign up. No key, no network:

```bash
python -m axiorank demo
```

In code, `inspect()` returns an advisory verdict (the default posture: deny on a
live secret, a destructive operation, or risk at or above 75):

```python
from axiorank import inspect

r = inspect("aws.s3.putObject", {
    "body": "AKIAIOSFODNN7EXAMPLE",
    "webhook": "http://attacker.example/exfil",
})
print(r.decision, r.risk)  # "deny" 96
print([s.detector for s in r.signals])  # ["secret.aws_access_key", ...]
```

`inspect_text(tool, text)` does the same for a tool's **output**, catching
indirect prompt injection before your agent ingests it.

## Enforce centrally

`inspect()` shows what is risky locally. To **enforce** it with your own policy,
an audit trail, approvals, and kill-chain correlation, create a free key at
[axiorank.com](https://www.axiorank.com) and route calls through the gateway.

## Quickstart (sync)

```python
import os
from axiorank import AxioRank

axio = AxioRank(api_key=os.environ["AXIORANK_API_KEY"])  # looks like axr_live_...

# Get the decision and act on it yourself:
result = axio.tool_call("github.push", {"repo": "myrepo"})
if result.decision == "deny":
    print(f"Blocked: {result.reason} (risk {result.risk})")
else:
    ...  # proceed with the real tool call
```

### `enforce()`: guard in one line

```python
from axiorank import AxioRank, AxioRankDeniedError

axio = AxioRank(api_key=os.environ["AXIORANK_API_KEY"])

try:
    axio.enforce("aws.delete_bucket", {"name": "prod-data"})
    delete_bucket("prod-data")  # only runs if AxioRank allowed it
except AxioRankDeniedError as e:
    log.warning("AxioRank blocked the call: %s", e.result.reason)
```

A `require_approval` policy holds the call for a human; `tool_call`/`enforce`
transparently wait out the hold and resolve to the final `allow`/`deny`.

## Quickstart (async)

```python
import os
from axiorank import AsyncAxioRank

async def main():
    async with AsyncAxioRank(api_key=os.environ["AXIORANK_API_KEY"]) as axio:
        result = await axio.tool_call("stripe.refund", {"amount": 5000})
        print(result.decision, result.risk)
```

## Preflight an external server before trusting it

```python
result = axio.verify_card(url="https://mcp.acme.com")
print(result.decision, result.identity.signature_valid, result.protocol)

# Or guard in one line; raises AxioRankCardDeniedError on `deny`:
axio.enforce_card(url="https://mcp.acme.com")
```

## Anthropic Messages API

The Anthropic SDK doesn't run your tools; your loop does. Guard the dispatch
step and send back the `tool_result` dicts it returns. Defaults to
`on_deny="return"`; the adapter never imports `anthropic` itself.

```python
import anthropic
from axiorank import AxioRank
from axiorank.integrations.anthropic import guard_tool_handlers

client = anthropic.Anthropic()
axio = AxioRank(api_key=os.environ["AXIORANK_API_KEY"])
dispatch = guard_tool_handlers({"deploy": lambda i: deploy(i["service"])}, axio)

msg = client.messages.create(model="claude-opus-4-8", tools=tools, messages=messages)
results = [dispatch(b) for b in msg.content if b.type == "tool_use"]
# send `results` back as the next user message
```

Async client? Use `guard_tool_handlers_async` (or `guard_tool_use` /
`guard_tool_use_async` to guard a single block).

## LangChain

```bash
pip install "axiorank[langchain]"
```

```python
from axiorank import AxioRank
from axiorank.integrations.langchain import AxioRankCallbackHandler

axio = AxioRank(api_key=os.environ["AXIORANK_API_KEY"])

# Every tool the agent runs is checked against your policies first; a blocked
# tool raises and the step fails.
agent_executor.invoke(
    {"input": "..."},
    config={"callbacks": [AxioRankCallbackHandler(axio)]},
)
```

Prefer a model-readable refusal over a raised exception? Wrap individual tools:

```python
from axiorank.integrations.langchain import guard_tool

safe_tool = guard_tool(my_tool, axio, on_deny="return")
```

## LlamaIndex

```bash
pip install "axiorank[llamaindex]"
```

```python
from axiorank.integrations.llamaindex import guard_tool

# Wrap any FunctionTool: its arguments are scored before it runs, and the
# schema, name, and description are preserved, so it is a drop-in replacement.
safe_tool = guard_tool(my_tool, axio)                      # raises on deny
recoverable = guard_tool(my_tool, axio, on_deny="return")  # model-readable refusal
```

## Pydantic AI

```bash
pip install "axiorank[pydantic-ai]"
```

```python
from axiorank.integrations.pydantic_ai import guard_tool

# Wrap a Tool; its name, description, and signature (schema) are preserved.
safe_tool = guard_tool(my_tool, axio)                       # sync tool
safe_async = guard_tool(my_tool, async_client=axio_async)   # async tool
```

## OpenAI Agents (Python)

```bash
pip install "axiorank[openai-agents]"
```

```python
from axiorank import AsyncAxioRank
from axiorank.integrations.openai_agents import guard_tool

axio = AsyncAxioRank(api_key=os.environ["AXIORANK_API_KEY"])

# The SDK runs tools async; a deny returns a refusal the model can re-plan around.
safe_tool = guard_tool(my_function_tool, axio, on_deny="return")
```

## Configuration

| Argument           | Default                       | Notes                                            |
| ------------------ | ----------------------------- | ------------------------------------------------ |
| `api_key`          | - (required)                  | Your agent's key (`axr_live_...`).               |
| `base_url`         | `https://app.axiorank.com`    | Point at your own deployment.                    |
| `timeout`          | `10.0`                        | Per-request timeout, in seconds.                 |
| `approval_timeout` | `300.0`                       | Max wait for a human to resolve a hold, seconds. |
| `client`           | a fresh `httpx.Client`        | Inject your own `httpx` client (tests, proxies). |

## License

MIT
