Skip to main content

APPSS analytics SDK for Python (async, Telegram bots, servers)

Project description

appss-sdk

Async Python SDK for APPSS analytics — events, user properties, and super properties — designed for Telegram bots and server-side workloads.

Install

pip install appss-sdk
# or
uv add appss-sdk

Optional extras for Telegram framework integration:

pip install appss-sdk[aiogram]    # aiogram v3
pip install appss-sdk[ptb]        # python-telegram-bot v20+

Quickstart

import asyncio
from appss_sdk import create_appss


async def main() -> None:
    appss = create_appss({"api_key": "YOUR_API_KEY", "debug": True})

    appss.track(
        distinct_id="user_42",
        event="message_received",
        properties={"chat_type": "private", "text_length": 12},
    )

    appss.set_user_properties("user_42", {
        "platform": "telegram",
        "username": "alice",
    })

    await appss.flush()
    await appss.destroy()


asyncio.run(main())

AppssClient is async-only — it must be instantiated inside a running event loop (asyncio.run(...), aiogram polling, FastAPI lifespan, etc.). The constructor starts a background flush loop, so creating it without an active loop will fail.

aiogram v3 integration

from aiogram import Bot, Dispatcher
from aiogram.types import Message
from appss_sdk import create_appss
from appss_sdk.telegram import from_aiogram_message

dp = Dispatcher()
appss = create_appss({"api_key": "YOUR_API_KEY"})


@dp.message()
async def on_message(message: Message) -> None:
    ctx = from_aiogram_message(message)
    if ctx is None:
        return
    appss.set_user_properties(ctx.distinct_id, ctx.properties)
    appss.track(ctx.distinct_id, "message_received", {"length": len(message.text or "")})
    await message.answer("✓")


# Call await appss.destroy() when shutting the bot down.

python-telegram-bot v20+ integration

from telegram import Update
from telegram.ext import Application, MessageHandler, filters, ContextTypes
from appss_sdk import create_appss
from appss_sdk.telegram import from_ptb_update

app = Application.builder().token("BOT_TOKEN").build()
appss = create_appss({"api_key": "YOUR_API_KEY"})


async def on_message(update: Update, _: ContextTypes.DEFAULT_TYPE) -> None:
    ctx = from_ptb_update(update)
    if ctx is not None:
        appss.set_user_properties(ctx.distinct_id, ctx.properties)
        appss.track(ctx.distinct_id, "message_received")


app.add_handler(MessageHandler(filters.TEXT, on_message))
app.run_polling()

Configuration

Field Type Default Description
api_key str Required. APPSS API key.
endpoint str https://appss-event-tracker-back-p.engagelabs.org API endpoint.
flush_interval_ms int 10_000 Automatic flush interval in milliseconds.
batch_size int 50 Auto-flush threshold by event count.
max_queue_size int 10_000 Maximum number of events buffered in memory.
request_timeout_ms int 30_000 HTTP request timeout in milliseconds.
retry RetryConfig exp. backoff with jitter Retry policy.
debug bool False Log to stdout/stderr.
on_error Callable[[AppssError], None | Awaitable[None]] None SDK error callback.
logger ILogger None Custom logger implementation.
queue IEventQueue None Custom queue (e.g. persistent).

RetryConfig accepts max_retries, base_backoff_ms, and max_backoff_ms. Every field is optional; defaults are filled in field by field.

Public API

from appss_sdk import (
    AppssClient,
    create_appss,
    AppssConfig,
    ResolvedConfig,
    RetryConfig,
    AppssError,
    ErrorCode,
    # ... concrete errors: ApiKeyRevokedError, NetworkError, etc.
    MemoryQueue,
    IEventQueue,
    ILogger,
    ITransport,
)
from appss_sdk.telegram import (
    from_aiogram_message,
    from_aiogram_callback,
    from_ptb_update,
    from_bot_api_update,
    ExtractedContext,
)

Telegram helpers are intentionally not re-exported at the root, so import appss_sdk does not pull aiogram/PTB into the import graph.

Client methods

  • appss.track(distinct_id, event, properties=None) — enqueue an event.
  • appss.set_user_property(distinct_id, key, value) — update a single user property.
  • appss.set_user_properties(distinct_id, properties) — update multiple user properties in a single POST.
  • appss.set_super_properties(properties) — register properties that are automatically attached to every subsequent track event.
  • appss.reset_super_properties() — clear all super properties.
  • await appss.flush() — force-send the queue.
  • await appss.destroy() — flush, stop background tasks, and close the HTTP client.

Lifecycle

AppssClient automatically registers SIGTERM and SIGINT handlers that invoke flush() before the process exits (Linux/macOS). On Windows add_signal_handler is unavailable — registration is a no-op, and you must call await appss.destroy() explicitly before exit.

Custom queue

from appss_sdk import create_appss, MemoryQueue


def on_overflow(dropped: int) -> None:
    print(f"appss: dropped {dropped} events")


appss = create_appss({
    "api_key": "...",
    "queue": MemoryQueue(max_size=5000, on_overflow=on_overflow),
})

You can also implement your own IEventQueue (e.g. backed by Redis); the contract is enqueue / drain / peek / size / is_empty / clear.

Wire protocol

POST /api/v1/events with body {"batch": [{"event", "distinct_id", "$insert_id", "timestamp", "properties"}]}, where timestamp is ISO 8601 in UTC and $insert_id is a UUID v4.

POST /api/v1/user-properties with body {"distinct_id", "properties"}.

Headers added automatically:

  • Authorization: Bearer <api_key>
  • Content-Type: application/json
  • X-Appss-Sdk: @appss-sdk/<version>
  • X-Appss-Protocol-Version: 1

Retry and error semantics

Status Action
2xx Success — the batch is drained from the queue.
400 Drop + ProtocolError (batch is dropped, not retried).
401 Stop forever — ApiKeyRevokedError, subsequent sends are blocked.
413 Recursive binary split + retry (halves until it fits).
429 Wait Retry-After (or fall back to exponential backoff if the header is invalid).
5xx Exponential backoff with jitter, up to retry.max_retries attempts.
Network exception Retry up to retry.max_retries, then MaxRetriesExceededError.

All errors are delivered to the on_error(error) callback if one is configured.

License

Apache-2.0. See LICENSE.

Project details


Download files

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

Source Distribution

appss_sdk-0.1.0.tar.gz (24.1 kB view details)

Uploaded Source

Built Distribution

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

appss_sdk-0.1.0-py3-none-any.whl (37.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: appss_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 24.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for appss_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ccf98d7067fe903eae1b2e1ca61557392248a174e935402d96f9f20d637c2e77
MD5 e1975b2fe321d931a20e5a4191ddff01
BLAKE2b-256 b4d4d03304c8454e02fef7b85aa282efb767af4d48d0d8f15eef9002747a5c6e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: appss_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 37.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for appss_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a9613adf1018b35b2cd779faa6746ee17afde91023bea2d83f77dd5cf6e61964
MD5 8e099ca386f2e49df85c099ba3cbfb42
BLAKE2b-256 ec9e38325a4128b4a34b74e88ce30cb7600320ba5078cc6a57905253692914a3

See more details on using hashes here.

Supported by

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