Skip to content

Python

The Whisperr server-side SDK for Python. The backend is where the highest-signal churn events live — payment failures, cancellations, trial expiry, usage drops — so this is where Whisperr gets its most valuable signal.

Terminal window
pip install whisperr
import os
from whisperr import Whisperr
whisperr = Whisperr(api_key=os.environ["WHISPERR_API_KEY"])
# A server-side churn signal:
whisperr.track("user_8842", "payment_failed", {"amount_cents": 4900, "reason": "card_declined"})
# Associate traits / contact channels with a user:
whisperr.identify("user_8842", email="ada@example.com", traits={"plan": "pro"})
# Deliver everything before the process exits:
whisperr.shutdown()

The user id is always explicit here — the server has no persisted session to infer it from. Pass the same id you use everywhere else and frontend + backend events land on one timeline.

settings.py
WHISPERR_API_KEY = os.environ["WHISPERR_API_KEY"]
MIDDLEWARE = [
# ... after your authentication middleware ...
"whisperr.django.WhisperrMiddleware",
]
views.py
def upgrade(request):
request.whisperr.track("plan_upgraded", {"plan": "pro"})
...

request.whisperr.track() is bound to the request’s authenticated user (request.user.pk by default; override with WHISPERR_RESOLVE_USER, a dotted path to def resolve(request) -> str | None). For events with no request — Celery tasks, webhooks, management commands — use a client directly with the user id from your domain data:

from whisperr.django import get_client
get_client().track(subscription.user_id, "subscription_cancelled", {"reason": reason})

Install the Django extra if you want the dependency pinned: pip install whisperr[django].

In scripts, serverless handlers, or management commands, call flush() (or shutdown()) before exit so queued events aren’t lost:

whisperr.track(user_id, "report_generated")
whisperr.flush()
  • Non-blocking. track()/identify() enqueue and return immediately; a background daemon thread batches and delivers. Call flush() for a barrier.
  • Reliable in-process. In-memory queue, batching, retry with backoff, per-event idempotency — the full delivery contract. The queue is not crash-durable; shutdown() is also registered via atexit.
  • Zero runtime dependencies. Standard library only.
Option Default Notes
api_key App ingestion key (wrk_…). Required.
base_url https://api.whisperr.net Ingestion base URL.
flush_at 20 Flush when this many events are queued.
flush_interval 10.0 Background flush cadence (seconds).
max_queue_size 10000 Oldest events drop on overflow.
max_batch_size 500 Events per batch (hard backend cap is 500).
max_retries 6 Consecutive retries before giving up a batch.
request_timeout 10.0 Per-request timeout (seconds).
disabled False No-op client (useful in tests).
debug False Verbose logging to stderr.
on_error Callable[[WhisperrError], None] for observability.