<p align="center">
  <img src="py_sdk500.png" alt="WhatsRB Cloud Python SDK" width="80" />
</p>

<h1 align="center">WhatsRB Cloud Python SDK</h1>

<h4 align="center">Official Python client for the <a href="https://whatsrb.com">WhatsRB Cloud</a> API.</h4>

<p align="center">
  Send WhatsApp messages, run AI agents, manage templates, and handle webhooks — all from Python.
</p>

## Installation

```bash
pip install whatsrb-cloud
```

## Quick Start

```python
import whatsrb_cloud

# Global configuration
whatsrb_cloud.configure(api_key="wrb_live_xxx")
client = whatsrb_cloud.client()

# Or direct initialization
client = whatsrb_cloud.WhatsrbCloud("wrb_live_xxx")
```

## Business Accounts

```python
# List accounts
accounts = client.business_accounts.list()
for account in accounts:
    print(account.display_name, account.phone_number)

# Send a text message
account = accounts[0]
message = account.send_text(to="+33612345678", text="Hello from Python!")

# Send a template
message = account.send_template(
    to="+33612345678",
    template_name="hello_world",
    template_language="en",
)

# Check conversation window
if account.window_open("+33612345678"):
    account.send_text(to="+33612345678", text="Window is open!")
```

## Sessions (WhatsApp Web)

```python
# Create a session
session = client.sessions.create(name="My Bot")

# Wait for QR scan
session.wait_for_qr(
    timeout=60,
    on_qr=lambda qr: print(f"Scan this QR: {qr}"),
)

# Send messages
session.send_message(to="+33612345678", text="Hello!")
session.send_image(to="+33612345678", url="https://example.com/image.jpg")
session.send_location(to="+33612345678", latitude=48.8566, longitude=2.3522)
```

## AI Agents

```python
# Create an agent
agent = client.agents.create(
    name="Support Bot",
    system_prompt="You are a helpful support agent.",
    model="gpt-4",
    allowed_actions=["support.ticket.create"],
)

# Run synchronously (blocks until complete)
run = agent.run(input={"message": "I need help"}, timeout=30)
print(run.suggested_reply)
print(run.intent, run.confidence)

# Run asynchronously
run = agent.run_async(input={"message": "I need help"})
# ... do other things ...
run.wait(timeout=30)

# Dispatch actions
from whatsrb_cloud import ActionRegistry

registry = ActionRegistry()
registry.register("support.ticket.create", lambda payload: create_ticket(payload))

results = run.dispatch(registry)
```

## Templates

```python
templates = client.templates("ba_xxx")

# List and filter
all_templates = templates.list()
approved = templates.list(status="approved")

# Find by name
welcome = templates.find_by_name("welcome_message")

# Sync from Meta
synced = templates.sync()

# Send test
templates.send_test("tpl_xxx", to="+33612345678", variables=["John"])
```

## Webhooks

```python
# Create a webhook
webhook = client.webhooks.create(
    url="https://example.com/webhook",
    events=["message.received", "agent_run.completed"],
)
print(webhook.secret)  # Only returned on creation

# Verify signatures
from whatsrb_cloud import WebhookSignature

is_valid = WebhookSignature.verify(
    payload=request_body,
    secret="whsec_xxx",
    signature=request.headers["X-Webhook-Signature"],
    timestamp=request.headers.get("X-Webhook-Timestamp"),
)

# Event registry
from whatsrb_cloud import EventRegistry

events = EventRegistry()
events.on("message.received", lambda data: print(f"New message: {data}"))
events.on("agent_run.completed", lambda data: handle_run(data))

events.dispatch(webhook_payload)
```

## Error Handling

```python
from whatsrb_cloud import WhatsrbCloud, NotFoundError, ValidationError, RateLimitError

client = WhatsrbCloud("wrb_live_xxx")

try:
    agent = client.agents.retrieve("agt_nonexistent")
except NotFoundError as e:
    print(f"Not found: {e} (status={e.status})")
except ValidationError as e:
    print(f"Validation: {e.details}")
except RateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after}s")
```

## Requirements

- Python 3.10+
- httpx >= 0.27

## License

MIT
