Metadata-Version: 2.4
Name: wapio
Version: 0.2.0
Summary: Official Python SDK for Wapio — send WhatsApp messages and manage WhatsApp sessions.
Project-URL: Homepage, https://www.wapio.io
Project-URL: Documentation, https://www.wapio.io/docs
Project-URL: Support, https://www.wapio.io/contact
Author-email: Wapio <support@wapio.io>
License: MIT
License-File: LICENSE
Keywords: api,chatbot,messaging,sdk,wapio,whatsapp,whatsapp-api
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
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: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1.0,>=0.27.0
Requires-Dist: typing-extensions>=4.5.0; python_version < '3.11'
Provides-Extra: dev
Requires-Dist: mypy>=1.8.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: respx>=0.21.0; extra == 'dev'
Requires-Dist: ruff>=0.3.0; extra == 'dev'
Description-Content-Type: text/markdown

# wapio

Official Python SDK for [Wapio](https://www.wapio.io). Send WhatsApp messages, manage WhatsApp sessions, contacts, groups, channels, and decrypt inbound media.

```sh
pip install wapio
```

Python 3.9+ is required.

## Features

- Sync and async clients built on `httpx`.
- Text, image, video, document, group, and channel message helpers.
- Session lifecycle: create, list, update, delete, connect, disconnect, QR, status, and key rotation.
- Contact management: list, details, profile picture, block, and unblock.
- Group management: list, metadata, participants add/remove, and settings.
- Inbound encrypted media decrypt helper.
- Rate-limit metadata and request IDs on every response.
- Automatic idempotency keys for message sends.

## Quickstart

```python
from wapio import Wapio

wapio = Wapio(api_key="bps_sk_...")

result = wapio.send_text(to="+15551234567", text="Hello from Wapio")
print(result.data["msgId"])
```

Use a context manager when you want the HTTP client closed automatically:

```python
with Wapio(api_key="bps_sk_...") as wapio:
    wapio.send_text(to="+15551234567", text="Hi")
```

## Async client

```python
import asyncio
from wapio import AsyncWapio

async def main():
    async with AsyncWapio(api_key="bps_sk_...") as wapio:
        result = await wapio.send_text(to="+15551234567", text="Hi")
        print(result.data["msgId"])

asyncio.run(main())
```

## Authentication

| Token | Format | Use |
| --- | --- | --- |
| Personal Access Token | `bps_pat_...` | Create, update, delete, connect, disconnect, and rotate WhatsApp sessions. |
| Session key | `bps_sk_...` | Send messages and read resources for one connected WhatsApp session. |

```python
wapio = Wapio(
    personal_access_token="bps_pat_...",
    api_key="bps_sk_...",
)
```

## Messages

```python
wapio.send_text(to="+15551234567", text="Hi")
wapio.send_image(to="+15551234567", image_url="https://example.com/image.jpg", caption="Image")
wapio.send_video(to="+15551234567", video_url="https://example.com/video.mp4")
wapio.send_document(
    to="+15551234567",
    document_url="https://example.com/file.pdf",
    file_name="file.pdf",
)
```

Pass your own idempotency key when you need retry deduplication across processes:

```python
wapio.send_text(
    to="+15551234567",
    text="Order #42 shipped",
    idempotency_key="order:42:shipped",
)
```

### Channels

Use the WhatsApp Channel ID ending in `@newsletter`.

```python
wapio.send_channel_message(
    "120363428122592568@newsletter",
    "This week's release is live",
)
```

### Message lifecycle

```python
info = wapio.get_message_info("bps_msg_...")
wapio.edit_message("bps_msg_...", "Corrected text")
wapio.delete_message("bps_msg_...")
```

## Sessions

```python
created = wapio.create_session(label="Support line")
session_id = created.data["session"]["session_id"]
raw_session_key = created.data["session_api_key"]["raw"]

sessions = wapio.list_sessions(status="connected", limit=50)
session = wapio.get_session(session_id)

wapio.update_session(session_id, label="Support EU")
wapio.get_session_qrcode(session_id)
wapio.get_session_status()
wapio.connect_session(session_id)
wapio.disconnect_session(session_id)

rotated = wapio.regenerate_api_key(session_id)
print(rotated.data["session_api_key"]["raw"])

wapio.delete_session(session_id)
```

Store `session_api_key.raw` when it is returned. It is shown once.

## Contacts

```python
wapio.get_contacts()
wapio.get_contact("+15551234567")
wapio.get_contact_profile_picture("+15551234567")
wapio.block_contact("+15551234567")
wapio.unblock_contact("+15551234567")
```

## Groups

```python
group = wapio.create_group(
    subject="Customer updates",
    participants=["15551234567@s.whatsapp.net"],
)
group_jid = group.data["group_jid"]

wapio.get_groups()
wapio.get_group_metadata(group_jid)
wapio.get_group_participants(group_jid)
wapio.add_group_participants(group_jid, ["15559876543@s.whatsapp.net"])
wapio.remove_group_participants(group_jid, ["15559876543@s.whatsapp.net"])
wapio.update_group_settings(group_jid, {"announce": True})

wapio.send_text(to=group_jid, text="Hello group")
```

## Media

For outbound media, pass a public HTTPS URL to `send_image`, `send_video`, or `send_document`.

Use `decrypt_media` for inbound encrypted WhatsApp media payloads:

```python
media = wapio.decrypt_media({
    "mediaKey": "...",
    "directPath": "...",
    "url": "https://mmg.whatsapp.net/...",
    "type": "image",
})
```

## Utilities

```python
wapio.get_user()
wapio.check_if_on_whatsapp("+15551234567")
```

## Errors

SDK methods raise `WapioAPIError` for API errors and `WapioConfigError` for missing credentials before a request is sent.

```python
try:
    wapio.send_text(to="+15551234567", text="Hi")
except Exception as exc:
    print(exc)
```
