Skip to main content

sukko

Asyncio-first Python client SDK for Sukko — realtime infrastructure proven correct under failure, deployed in your own cloud. Real-time market-data / event subscription for backend services, data pipelines, and notebooks.

  • Async-iterator delivery with capability-gated back-pressure — no unbounded buffering, no silent drops.
  • Full gap recovery — reconnect-with-replay, advisory gap → live replay, and history.
  • Automatic single-flight auth — proactive + reactive token refresh, API-key → JWT escalation.
  • WebSocket + SSE transports, awaitable REST publish, push subscription management.
  • Jupyter-safe sync wrapper (SyncSukkoClient) — no asyncio boilerplate.
  • Fully typed (py.typed), built to the AsyncAPI v1.4.0 + gateway OpenAPI contracts.
pip install sukko

Requires Python 3.11+.

Quickstart (async)

import asyncio
from sukko import SukkoClient

async def main():
    async with SukkoClient("wss://gateway.example.com/ws", token="<jwt>") as client:
        await client.subscribe(["acme.trades"])
        async for msg in client.messages():
            print(msg.channel, msg.data)          # live + recovered messages arrive here

asyncio.run(main())

Quickstart (sync — scripts & notebooks)

from sukko import SyncSukkoClient

with SyncSukkoClient("wss://gateway.example.com/ws", token="<jwt>") as client:
    client.subscribe(["acme.trades"])
    for msg in client.stream():                    # blocking; Jupyter-safe (own background loop)
        print(msg.channel, msg.data)

Publishing

await client.publish("acme.trades", {"price": 100})              # over the WS connection (fire-and-forget)
mid = await client.rest_publish("acme.trades", {"price": 100})   # awaitable REST — no WS needed (all editions)

rest_publish returns the server-assigned stable message identity mid — the same mid subscribers see on the delivered message (None on multi-topic fan-out). Delivered messages carry msg.mid on every copy (live, gap-replay, and history), so it can be used to deduplicate — e.g. dropping the overlap between a reconnect replay and messages already received.

Auth

Credentials are sent via request headers by default (Authorization: Bearer / X-API-Key); pass auth_via="query" to opt into query-param auth. Long-lived tokens are refreshed automatically (supply a get_token async callback). An API-key connection can escalate to a JWT mid-session:

client = SukkoClient(url, api_key="<key>", get_token=fetch_fresh_jwt)
...
await client.escalate("<jwt>")   # gains JWT permissions; re-subscribes newly-permitted channels

Channels

Channels are "{tenant}.{suffix}" (the tenant is the segment before the first dot; the suffix is an opaque dotted remainder). Helpers:

from sukko import build_channel, parse_channel
build_channel("acme", "trades.btc")   # -> "acme.trades.btc"
parse_channel("acme.trades.btc")      # -> ParsedChannel(tenant="acme", suffix="trades.btc")

Recovery

On a Kafka backend the SDK recovers missed messages automatically: it reconnects with exponential backoff + jitter and replays from the last position, and turns advisory gap notices into live replays — all surfaced through the same messages() stream (recovered records carry history / pos). The delivery guarantee is at-least-once within the replay window, best-effort beyond. On the Direct backend (no positions), a disconnect surfaces a PossibleGap signal per channel so data loss is never silent.

You can also fetch history explicitly (all editions, when the server has history enabled):

await client.history("acme.trades", limit=50)   # arrives as history-flagged messages

Push subscription management (Web Push = Pro; mobile FCM/APNs = Enterprise)

Register a mobile/browser device for push on a user's behalf (this SDK does not receive push):

device_id = await client.push.subscribe(platform="android", channels=["acme.alerts"], token="<fcm>")
await client.push.unsubscribe(device_id)
key = await client.push.get_vapid_key()

Errors

Every failure is a typed subclass of sukko.SukkoError — e.g. NotConnectedError, EditionRequiredError, RateLimitError, RecoveryInterruptedError, PublishError. Credentials are never present in an error message, repr, or log record.

Engineering

  • Engineering principles — the rules this SDK is built and reviewed against. Code comments cite them by section: # per §VI refers to section VI of that document (or of the platform principles it adapts — each heading carries the cross-reference).
  • Architecture decision records — durable decisions with context and rejected alternatives; comments cite them as ADR-NNNN.

License

MIT — see LICENSE.

Metadata

Release files for sukko 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sukko 0.1.2
File Size Uploaded Provenance
sukko-0.1.2.tar.gz 108.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sukko 0.1.2
File Interpreter ABI Platform
sukko-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 169.7 kB

Release files / sukko-0.1.2.tar.gz

Download URL sukko-0.1.2.tar.gz
Size 108.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9733a772b221af94a2a7458d219c171ddd2db8388caf49d03a08332a82dc9f3e
BLAKE2b-256 checksum
How to use checksums
9931e421cffe1a08a1e35431b966abf699546f13a9390618bbe12b854a450cef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / sukko-0.1.2-py3-none-any.whl

Download URL sukko-0.1.2-py3-none-any.whl
Size 61.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a12e397464d0161b7a8efd0d64f8ed716927d06904bf657ba45925cfb2669a5
BLAKE2b-256 checksum
How to use checksums
e6640721f75ff05f561c81942bb7bffba4d592e70588639939421df75374c79f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for sukko 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for sukko-0.1.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page