Metadata-Version: 2.4
Name: aguard
Version: 0.1.0
Summary: Official Python SDK for AgentGuard — the AI action firewall
Project-URL: Homepage, https://agentguard.dev
Project-URL: Repository, https://github.com/agentguard/agentguard-python
Project-URL: Documentation, https://agentguard.dev/docs
Author-email: AgentGuard <hello@agentguard.dev>
License: MIT
License-File: LICENSE
Keywords: agent,agentguard,ai,firewall,llm,security
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Requires-Dist: httpx>=0.24.0
Description-Content-Type: text/markdown

# agentguard

Official Python SDK for [AgentGuard](https://agentguard.dev) — the AI action firewall that keeps your agents safe.

## Install

```bash
pip install agentguard
```

**Requirements:** Python 3.8 or later.

## Quick Start

```python
from agentguard import AgentGuard

guard = AgentGuard(api_key="ag_live_YOUR_KEY_HERE")
```

Then, before your agent executes any action:

```python
result = guard.check(
    action="send_email",
    payload={"to": "user@example.com", "body": "Hello!"},
)

if result.decision == "block":
    raise Exception(f"Action blocked: {result.reason}")

# proceed with the action
```

## Constructor Options

```python
AgentGuard(
    api_key: str,          # required — from your AgentGuard dashboard
    base_url: str = None,  # default: https://agentguard.dev/api
                           # also read from AGENTGUARD_BASE_URL env var
    timeout: float = 5.0,  # request timeout in seconds
)
```

The `base_url` is resolved in this order:
1. `base_url` argument passed to the constructor
2. `AGENTGUARD_BASE_URL` environment variable
3. `https://agentguard.dev/api` (production default)

## `guard.check()` Reference

```python
result = guard.check(
    action: str,                        # required — name of the action
    payload: dict,                      # required — data the agent is acting on
    agent_id: str | None = None,        # which agent is acting (improves logging)
    app_user_id: str | None = None,     # end user ID (enables cross-user detection)
    app_name: str | None = None,        # identifies your app in the dashboard
    risk_context: dict | None = None,   # extra metadata for risk scoring
)
```

### Return value — `CheckResult`

```python
@dataclass
class CheckResult:
    decision: Literal["allow", "block", "review"]
    risk_level: Literal["low", "medium", "high", "critical"]
    reason: str
    log_id: int | None
    prompt_injection_detected: bool
```

## Handling Each Decision

```python
result = guard.check(action=action, payload=payload)

if result.decision == "allow":
    # Safe to proceed. Execute the action.
    execute_action(action, payload)

elif result.decision == "review":
    # High-risk but not definitively malicious.
    # Queue for human review or notify your security team.
    queue_for_review(action, payload, result.reason)

elif result.decision == "block":
    # Policy violation or detected threat. Do NOT proceed.
    raise Exception(f"Blocked ({result.risk_level}): {result.reason}")
```

## Error Handling

```python
from agentguard import (
    AgentGuard,
    AgentGuardAuthError,
    AgentGuardNetworkError,
    AgentGuardServerError,
)

try:
    result = guard.check(action=action, payload=payload)
except AgentGuardAuthError as e:
    # Invalid or expired API key — check your dashboard
    print(f"Auth error: {e}")
except AgentGuardNetworkError as e:
    # Connectivity issue — the SDK already retried once
    # Fall back gracefully (allow or queue for later)
    print(f"Network error: {e}")
except AgentGuardServerError as e:
    # Unexpected server error (5xx)
    print(f"Server error {e.status_code}: {e}")
```

The SDK automatically retries once on network errors. Auth errors and server errors are never retried.

## Example — Flask Route

```python
from flask import Flask, request, jsonify
from agentguard import AgentGuard
import os

guard = AgentGuard(api_key=os.environ["AGENTGUARD_KEY"])
app = Flask(__name__)

@app.post("/agent/send-email")
def send_email():
    data = request.get_json()
    result = guard.check(
        action="send_email",
        payload={"to": data["to"], "body": data["body"]},
        app_user_id=data.get("userId"),
        agent_id=data.get("agentId"),
    )

    if result.decision == "block":
        return jsonify({"error": result.reason}), 403

    # send the email...
    return jsonify({"ok": True})
```

## Publishing to PyPI

When you're ready to publish:

```bash
cd sdks/python
pip install build twine
python -m build
twine upload dist/*
```

Make sure your `pyproject.toml` has the correct `name`, `version`, and `license` fields before publishing.

## Links

- [Dashboard](https://agentguard.dev/dashboard) — manage API keys and view logs
- [API Reference](https://agentguard.dev/docs) — raw HTTP API docs
- [GitHub](https://github.com/agentguard) — source code and issues
