Metadata-Version: 2.4
Name: agentweb-client
Version: 0.2.0
Summary: Dependency-free Python client for the AgentWeb API.
License-Expression: Apache-2.0
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"

# AgentWeb Python client

A small, dependency-free Python client for the AgentWeb API. Stdlib only
(`urllib`, `hmac`) — nothing to install transitively. Use it on your backend;
the API key is a server secret and must never reach a browser.

```bash
pip install agentweb-client   # or: uv add agentweb-client
```

## Use it

```python
from agentweb_sdk import AgentWeb

aw = AgentWeb(api_key="sk_live_...")  # or base_url=... for a private deployment

# Render only integrations that work in this customer surface.
integrations = aw.integrations.list(host_context="web")

# 1. Mint a single-use sign-in link and send it to your user.
link = aw.connections.create(
    end_user_id="user_42",                     # your own id for the person
    integration_id="amazon",
    return_url="https://app.example.com/connected",
)
print(link["connect_url"])

# 2. After the connection.created webhook fires, act as that user.
result = aw.execute(
    end_user_id="user_42",
    integration_id="amazon",
    operation="orders.list",
    arguments={"limit": 5},
    idempotency_key="orders-list-user42-0001",  # reuse on retry for writes
)
print(result["data"])

# List / revoke
aw.connections.list("user_42")
aw.connections.revoke("user_42", "amazon")
```

Calendar, Contacts, Messages, Notes, and Reminders are returned as device
capabilities. They do not have hosted connect URLs. Callers should check
`compatible_with_host` and `connect_url_supported` before rendering a connect
control.

Every method returns the wire payload verbatim (snake_case, exactly what `curl`
shows). Failures raise `AgentWebError` carrying the service's own `code` and
`kind` — match on `code`, never on the message:

```python
from agentweb_sdk import AgentWebError

try:
    aw.execute(end_user_id="user_42", integration_id="amazon",
               operation="orders.list", arguments={})
except AgentWebError as err:
    if err.code == "connection_needs_reauth":
        ...  # send the user a fresh connect link
    print(err.code, err.kind, err.status, err.retryable)
```

## Verify webhooks

Pass the **raw** request body bytes (the signature is over the exact bytes sent),
the `X-AgentWeb-Signature` header, and your webhook secret. Constant-time.

```python
from agentweb_sdk import verify_webhook

# FastAPI
@app.post("/webhooks/agentweb")
async def hook(request: Request):
    raw = await request.body()
    sig = request.headers.get("X-AgentWeb-Signature", "")
    if not verify_webhook(raw, sig, WEBHOOK_SECRET):
        raise HTTPException(401)
    event = json.loads(raw)          # {"type": "connection.created", ...}
```

## A fully generated client

This SDK is a hand-written, ergonomic surface over the common calls. If you want
a client covering every endpoint, generate one from the live OpenAPI spec:

```bash
python sdk/python/scripts/dump_openapi.py > openapi.json
openapi-python-client generate --path openapi.json
```
