rmyndharis-openwa
Official Python SDK for the OpenWA WhatsApp API Gateway.
A synchronous client built on httpx, with bundled type hints (PEP 561).
Install
pip install rmyndharis-openwa
Requires Python 3.9+. The importable module is openwa.
Usage
from openwa import OpenWAClient
client = OpenWAClient(
base_url="https://your-gateway.example.com",
api_key="owa_k1_…",
)
client.sessions.start("my-session")
result = client.messages.send_text("my-session", {
"chatId": "628123456789@c.us",
"text": "Hello from the OpenWA Python SDK!",
})
print(result["messageId"])
The client is also a context manager (it closes the underlying connection pool on exit):
with OpenWAClient(base_url="…", api_key="…") as client:
client.messages.send_text("my-session", {"chatId": "…@c.us", "text": "hi"})
For tests, pass an httpx transport — no global monkey-patching required:
import httpx
client = OpenWAClient(base_url="…", api_key="…", transport=httpx.MockTransport(handler))
Search
GET /search is wrapped as client.search.search(params). Only q is required;
the rest (sessionId, chatId, direction, type, from, dateFrom,
dateTo, limit, offset) are optional. dateFrom / dateTo are epoch-ms.
The active search provider (built-in DB full-text, or a plugin) answers; if none
is configured the server returns 501.
res = client.search.search({"q": "invoice", "sessionId": "my-session", "limit": 20})
for hit in res["hits"]:
print(hit["snippet"], hit["score"])
Messaging
Voice notes: pass
ptt=Trueinside the body dict tosend_audioto send a real WhatsApp voice note (PTT). Supplyaudio/ogg; codecs=opusaudio for reliable playback; the server defaults the mimetype to that whenpttis set without one.
Errors
A non-2xx response raises a typed OpenWAApiError subclass — OpenWAAuthError (401),
OpenWAForbiddenError (403), OpenWANotFoundError (404), OpenWAConflictError (409),
OpenWARateLimitError (429), OpenWANotImplementedError (501) — each carrying .status
and the parsed .body. A timeout raises OpenWATimeoutError.
from openwa import OpenWANotFoundError
try:
client.sessions.get("missing")
except OpenWANotFoundError as e:
print(e.status) # 404
Notes
- Use HTTPS in production — the API key is sent as
X-API-Keyand is bearer-equivalent. - The SDK does not retry, and never follows redirects (so the key is never re-sent to a redirect target). Path segments are percent-encoded; a base-URL path prefix (e.g. behind a reverse proxy) is preserved.
- Escape hatch for endpoints the SDK does not wrap:
client.request(method, path, query=…, body=…).
License
MIT