Skip to main content

woku

Official server-side SDK for the Woku management API.

PyPI Python License

Why

Manage your entire Woku account from your backend with one typed client: trackers, VoC tools (NPS/CSAT/CES), wokus, forms, flows, action plans, support tickets, delivery tracking and survey sends over the public /v1 API.

  • Sync and async clients (Woku / AsyncWoku) on top of httpx.
  • Typed request bodies (Pydantic v2 models generated from the OpenAPI spec) and response shapes.
  • Automatic retries with full-jitter backoff and Retry-After support.
  • Idempotent creates: creates carry an auto-generated Idempotency-Key, so a retry after a blip never creates twice. Action calls (send, test, reply) are never silently replayed.
  • Auto-paginated lists: for ticket in woku.tickets.list(): ....
  • Typed errors with the server request_id for support.

Server-only. The secret key grants full management access. Keep it on your backend, never in a browser, mobile app or other client you do not control.

Install

pip install woku
# or: uv add woku

Requires Python 3.9+.

Quickstart

from woku import Woku

woku = Woku(api_key="sk_...")  # or set WOKU_API_KEY and call Woku()

# Create a tracker definition (idempotent).
tracker = woku.trackers.create({"name": "Store #1", "system": "retail"})

# Create an NPS tool and send it.
tool = woku.nps_tools.create(
    {"name": "Post-purchase", "npsMessage": "How likely are you to recommend us?"}
)
woku.nps.send_invitations(
    {"channel": "email", "npsToolId": tool["_id"], "recipients": ["ana@example.com"]}
)

# Read delivery + response rate.
stats = woku.dispatches.stats({"channel": "email"})
print(stats["responseRate"])

The key is read from WOKU_API_KEY when you omit api_key. You can also pass it directly: Woku("sk_...").

Request bodies accept either a plain dict (as above) or a generated Pydantic model from woku._generated.models.

Async

import asyncio
from woku import AsyncWoku


async def main() -> None:
    async with AsyncWoku(api_key="sk_...") as woku:
        async for ticket in await woku.tickets.list({"severity": "high"}):
            print(ticket["title"])


asyncio.run(main())

Pagination

List methods return a page you can iterate item by item across pages, or walk page by page:

for ticket in woku.tickets.list({"severity": "high"}):
    print(ticket["title"])

first = woku.dispatches.list({"channel": "whatsapp"})
if first.has_next_page():
    second = first.get_next_page()

Errors

Every failure is a WokuError. HTTP errors are typed subclasses carrying the status, parsed body and request_id:

from woku import NotFoundError, RateLimitError

try:
    woku.tickets.get("nonexistent")
except NotFoundError as err:
    print(err.status, err.request_id)  # 404, "req_..."
except RateLimitError as err:
    print("retry after", err.retry_after_seconds)

Transport failures (DNS/TLS/timeout) are WokuConnectionError / WokuTimeoutError.

Configuration

Woku(
    api_key="sk_...",
    base_url="https://clientapi.woku.app",  # default
    timeout=60.0,  # seconds, default
    max_retries=2,  # default
)

Per-call overrides go in the options argument of any method:

woku.tickets.list({"severity": "high"}, options={"timeout": 10.0, "max_retries": 0})
woku.nps_tools.create(body, options={"idempotency_key": "my-key"})

Resources

trackers, nps_tools / csat_tools / ces_tools, nps / csat / ces, wokus, forms, flows, action_plans, action_plan_groups, tickets, ticket_destinations, dispatches, reports, company, quarantines.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

woku-0.1.0.tar.gz (40.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

woku-0.1.0-py3-none-any.whl (34.7 kB view details)

Uploaded Python 3

File details

Details for the file woku-0.1.0.tar.gz.

File metadata

  • Download URL: woku-0.1.0.tar.gz
  • Upload date:
  • Size: 40.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for woku-0.1.0.tar.gz
Algorithm Hash digest
SHA256 812072fa98177de4578263b54f50676d8d96ac787862aceebc049207645431af
MD5 97faaa7c6f0f51e0dc371c9a627bd604
BLAKE2b-256 2080bcaf79b1dd14a0ebe0ca3e09ce4e17ea86067a8487f8c65af6a7a8307b74

See more details on using hashes here.

File details

Details for the file woku-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: woku-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 34.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for woku-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1abbbcd9d5d21e9b4171bdf02b7f3ed0512f4d75b75570c06feec05c961cb1c4
MD5 2e55990099f4e3001cb69f7fbb5be96d
BLAKE2b-256 5a539a813f2f301bdfbb2ec3ca31a7ff9392cff4f8bfbb9e6aece3203c9d398b

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page