Skip to content
LogZuno

Python event tracking

Send events to LogZuno from Python, with code that is tested against the API.

This example sends one event to LogZuno's ingestion API from Python. It is the exact file our snippet tests send to the API before the docs are published.

Requirements

Python 3.8 or later. Only the standard library: no packages to install.

Send an event

# Python 3, standard library only.
import json
import os
import urllib.error
import urllib.request

endpoint = os.environ.get("LOGZUNO_ENDPOINT", "https://api.logzuno.app/v1")

request = urllib.request.Request(
    f"{endpoint}/log",
    method="POST",
    headers={
        "Authorization": f"Bearer {os.environ['LOGZUNO_API_KEY']}",
        "Content-Type": "application/json",
    },
    data=json.dumps({
        "channel": "signups",
        "event": "User signed up",
        "user_id": "user-123",
        "icon": "🎉",
        "notify": True,
        "tags": {"plan": "growth", "source": "website"},
    }).encode(),
)

try:
    with urllib.request.urlopen(request, timeout=10) as response:
        print(response.status, response.read().decode())
except urllib.error.HTTPError as error:
    # 4xx and 5xx responses: the body says why (and, for 429, when to retry).
    print(error.code, error.read().decode())

Export LOGZUNO_API_KEY and run python3 logzuno.py. LogZuno answers 202 and the event appears in your project's live feed within seconds. Keep the key in an environment variable or your secrets manager, not in source control.

Notes for Python

Errors raise. urllib raises HTTPError for 4xx and 5xx responses; the example catches it and prints LogZuno's message. On 429, read error.headers["Retry-After"] and wait that many seconds before resending.

Requests or httpx. If your project already uses them, send the same JSON body and Authorization header with requests.post or httpx.post.

Web apps. In Django, Flask or FastAPI, send from a background task or queue (Celery, RQ, FastAPI's BackgroundTasks) rather than inside the request.

What the request contains

The body is the same in every language: a channel and an event, and optionally user_id, group_id, description, icon, notify and tags. All fields, limits and response codes are in sending events and the ingestion API reference.