Skip to main content

Sockudo Python client SDK

Project description

sockudo-python

Async Sockudo client SDK for Python.

sockudo-python is a Pusher-compatible realtime client for Python applications. It preserves the familiar subscribe/bind/channel model while adding Sockudo-native features such as filter-aware subscriptions, delta reconstruction, and encrypted channel handling.

Features

  • Protocol V2 by default, with V1 compatibility
  • Public, private, presence, and encrypted channels
  • Proxy-backed presence history and presence snapshot helpers
  • Tag filter and per-subscription event filter helpers
  • Continuity-aware connection recovery (stream_id + serial)
  • Message deduplication
  • JSON, MessagePack, and Protobuf wire formats
  • Fossil and Xdelta3/VCDIFF delta compression support
  • User sign-in and watchlist event handling

Install

For apps, install the published package:

pip install sockudo-python

For local monorepo development, install from the local path:

git clone https://github.com/sockudo/sockudo.git
pip install -e sockudo/client-sdks/sockudo-python

Using requirements.txt for local development:

-e ../sockudo/client-sdks/sockudo-python

Using pyproject.toml for local development:

[project]
dependencies = [
  "sockudo-python @ file:///absolute/path/to/sockudo/client-sdks/sockudo-python",
]

From this workspace:

pip install -e client-sdks/sockudo-python

Quick Start

import asyncio

from sockudo_python import SockudoClient, SockudoOptions


async def main() -> None:
    client = SockudoClient(
        "app-key",
        SockudoOptions(
            cluster="local",
            force_tls=False,
            ws_host="127.0.0.1",
            ws_port=6001,
        ),
    )

    channel = client.subscribe("public-updates")
    channel.bind("price-updated", lambda payload, meta: print(payload))

    await client.connect()
    await asyncio.sleep(30)
    await client.disconnect()


asyncio.run(main())

Advanced Usage

Private Channel Authorization

Use an endpoint URL (the default) or supply a fully custom async handler:

from sockudo_python import (
    SockudoClient,
    SockudoOptions,
    ChannelAuthorizationOptions,
    ChannelAuthorizationData,
    ChannelAuthorizationRequest,
)


async def my_auth_handler(request: ChannelAuthorizationRequest) -> ChannelAuthorizationData:
    # Call your own backend to produce a signed auth token.
    return ChannelAuthorizationData(
        auth="app-key:hmac-sha256-signature",
        channel_data='{"user_id":"42"}',
    )


client = SockudoClient(
    "app-key",
    SockudoOptions(
        cluster="local",
        ws_host="127.0.0.1",
        ws_port=6001,
        channel_authorization=ChannelAuthorizationOptions(
            endpoint="https://api.example.com/sockudo/auth",
            # Or override entirely:
            custom_handler=my_auth_handler,
        ),
    ),
)

channel = client.subscribe("private-orders")
channel.bind("order-placed", lambda data, meta: print(data))

await client.connect()

Presence Channels

channel = client.subscribe("presence-lobby")

channel.bind(
    "pusher:subscription_succeeded",
    lambda data, meta: print("members:", data),
)
channel.bind(
    "pusher:member_added",
    lambda data, meta: print("joined:", data),
)
channel.bind(
    "pusher:member_removed",
    lambda data, meta: print("left:", data),
)

await client.connect()

Presence History

Client-side presence history is proxy-backed. The Python client does not sign the server REST API directly; configure a backend endpoint that accepts {channel, params, action} and proxies the request with server credentials.

from sockudo_python import PresenceHistoryOptions, PresenceHistoryParams, PresenceSnapshotParams

client = SockudoClient(
    "app-key",
    SockudoOptions(
        cluster="local",
        ws_host="127.0.0.1",
        ws_port=6001,
        presence_history=PresenceHistoryOptions(
            endpoint="https://api.example.com/sockudo/presence-history",
        ),
    ),
)

channel = client.subscribe("presence-lobby")

page = await channel.history(
    PresenceHistoryParams(limit=50, direction="newest_first")
)
if page.has_next():
    next_page = await page.next()

snapshot = await channel.snapshot(PresenceSnapshotParams(at_serial=4))

Filter-Aware Subscriptions

Server-side tag filtering is a V2 feature. Only messages whose tags match the filter expression are delivered to this subscription.

from sockudo_python import SubscriptionOptions, Filter

channel = client.subscribe(
    "price:btc",
    options=SubscriptionOptions(
        filter=Filter.eq("market", "spot"),
    ),
)

# Compound filters
channel = client.subscribe(
    "price:btc",
    options=SubscriptionOptions(
        filter=Filter.and_(
            Filter.eq("market", "spot"),
            Filter.gt("spread", "0"),
        ),
    ),
)

Delta Compression And Rewind

Request delta-compressed delivery to reduce bandwidth for channels that carry frequently-updated payloads:

from sockudo_python import SubscriptionOptions, ChannelDeltaSettings, DeltaAlgorithm

channel = client.subscribe(
    "orderbook:btc-usd",
    options=SubscriptionOptions(
        delta=ChannelDeltaSettings(
            enabled=True,
            algorithm=DeltaAlgorithm.XDELTA3,
        ),
    ),
)
channel.bind("snapshot", lambda data, meta: print(data))

channel = client.subscribe(
    "market:btc",
    options=SubscriptionOptions(
        rewind=SubscriptionRewind.seconds_back(30),
    ),
)

client.bind("sockudo:resume_success", lambda data, _: print(data))
channel.bind("sockudo:rewind_complete", lambda data, _: print(data))

Encrypted Channels

private-encrypted-* channels decrypt payloads automatically using the shared_secret returned by your auth endpoint or custom handler.

channel = client.subscribe("private-encrypted-documents")
channel.bind("doc-updated", lambda data, meta: print(data))  # data is already decrypted

Your auth handler must populate shared_secret in ChannelAuthorizationData:

async def encrypted_auth(request: ChannelAuthorizationRequest) -> ChannelAuthorizationData:
    return ChannelAuthorizationData(
        auth="app-key:hmac-sha256-signature",
        shared_secret="base64-encoded-32-byte-secret",
    )

User Sign-In

from sockudo_python import UserAuthenticationOptions


client = SockudoClient(
    "app-key",
    SockudoOptions(
        cluster="local",
        ws_host="127.0.0.1",
        ws_port=6001,
        user_authentication=UserAuthenticationOptions(
            endpoint="https://api.example.com/sockudo/user-auth",
        ),
    ),
)

await client.connect()
await client.user.sign_in()

Connection Lifecycle

Bind to connection state changes to react to connect, disconnect, and reconnect events:

def on_state_change(change) -> None:
    print(f"connection: {change.previous} -> {change.current}")

client.connection.bind("state_change", on_state_change)
client.connection.bind("connected", lambda data, _: print("socket id:", data.get("socket_id")))
client.connection.bind("disconnected", lambda data, _: print("disconnected"))
client.connection.bind("error", lambda data, _: print("error:", data))

await client.connect()

Protocol V2

V2 is the default. To explicitly request it or to downgrade to V1 for strict Pusher SDK compatibility:

# V2 (default) — enables continuity tokens, message_id, recovery, filters, delta
client = SockudoClient("app-key", SockudoOptions(cluster="local", protocol_version=2))

# V1 — plain Pusher protocol, compatible with official Pusher SDKs
client = SockudoClient("app-key", SockudoOptions(cluster="local", protocol_version=1))

Requirements

  • Python 3.11+
  • asyncio-based; designed for use with async/await

Testing

Run the unit and integration test suite:

pytest client-sdks/sockudo-python/tests

Live integration tests against a local Sockudo server on port 6001:

SOCKUDO_LIVE_TESTS=1 pytest client-sdks/sockudo-python/tests

The live suite covers:

  • public subscribe + publish round-trip
  • delta-enabled channel delivery
  • encrypted channel decryption

CI/CD

GitHub Actions are managed from the monorepo root:

  • CI: .github/workflows/sdk-ci.yml
  • Publish: .github/workflows/sdk-release.yml with tag client-python-vX.Y.Z
  • Setup: see docs/sdk-publishing-2026.md for PyPI trusted publishing.

Status

The package covers the core Sockudo feature set, including VCDIFF decoding, encrypted channel handling, and both supported delta algorithms, and is suitable for publishing as the official Python SDK.

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

sockudo_python-2.0.0.tar.gz (27.1 kB view details)

Uploaded Source

Built Distribution

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

sockudo_python-2.0.0-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

Details for the file sockudo_python-2.0.0.tar.gz.

File metadata

  • Download URL: sockudo_python-2.0.0.tar.gz
  • Upload date:
  • Size: 27.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sockudo_python-2.0.0.tar.gz
Algorithm Hash digest
SHA256 f561c248a783ec8889c1344c54f0cb016af47d489f5f064aeb992f2ad5f51e68
MD5 c346c7efe62f4e5c3902f23f2034bdf9
BLAKE2b-256 f94aa51ad7b6b730e74d93ebdb8e9a851e683bfbe44b8087eb21e7c56fa593c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for sockudo_python-2.0.0.tar.gz:

Publisher: sdk-release.yml on sockudo/sockudo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sockudo_python-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: sockudo_python-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 22.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sockudo_python-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fd779a911509a0d86784ad37514e2d4c49a36e2b35267285f2ab398cd2e30f72
MD5 d8493100751655d28ef64e09c514cdca
BLAKE2b-256 8b5486615d6b029ab15e9440db7d40e317040dccbd8986e3ba7bf9788cea3ccb

See more details on using hashes here.

Provenance

The following attestation bundles were made for sockudo_python-2.0.0-py3-none-any.whl:

Publisher: sdk-release.yml on sockudo/sockudo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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