WuKongIM Docs

Python quickstart

Install a pinned WuKongEasySDK-Python PyPI version and use asyncio for online messaging, heartbeat, reconnect, and cleanup.

WuKongEasySDK-Python follows JS v2.0.4 and uses Python 3.11+, asyncio, and websockets for WebSocket JSON-RPC CONNECT, online messaging, automatic RECVACK, heartbeat, reconnect, and custom events.

1. Install a pinned version

This tutorial uses PyPI wukong-easy-sdk==0.1.0 and requires Python 3.11+. The distribution name is wukong-easy-sdk; the import name is wukong_easy_sdk.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --index-url https://pypi.org/simple "wukong-easy-sdk==0.1.0"

On Windows PowerShell, replace activation with .venv\Scripts\Activate.ps1. The runtime dependency is websockets>=15.0.1,<18; uv.lock pins development and validation dependencies.

2. Prepare Alice and Bob

Follow authentication and Tokens so your trusted backend supplies each user's uid, token, and websocketUrl. Clients connect to the Gateway and do not call Product HTTP management endpoints.

Device categories are APP 0, WEB 1, and PC/Desktop 2. Python defaults to Desktop 2; provision the Token for that same device category. The usual development address is ws://127.0.0.1:5200. Use ws://127.0.0.1:5200/ws only when the listener or proxy configures /ws. Use a reachable client address across machines and wss:// in production.

Download the matching example source and keep using the same virtual environment:

git clone --branch v0.1.0 --depth 1 https://github.com/WuKongIM/WuKongEasySDK-Python.git

In two terminals, set each user's WKIM_UID, WKIM_TOKEN, WKIM_PEER, and optional WKIM_URL, then run:

python WuKongEasySDK-Python/examples/chat.py

For Alice, set WKIM_UID=alice and WKIM_PEER=bob; reverse these for Bob. Supply each Token through its trusted environment. Once both display Connected, send in both directions. Enter /quit to clean up. The example deliberately displays chat content; the SDK is silent by default.

3. Connect and send in your application

This example sends as Alice and keeps receiving for 10 seconds. Bob must already be online. In a real application, keep the client alive until application shutdown.

import asyncio
import os

from wukong_easy_sdk import AuthOptions, WKIM, WKIMChannelType, WKIMEvent


async def main():
    im = WKIM.init(
        os.environ.get("WKIM_URL", "ws://127.0.0.1:5200"),
        AuthOptions(uid="alice", token=os.environ["WKIM_TOKEN"]),
    )

    def receive(message):
        # Pass message["payload"] to your application's UI or bounded queue.
        # Never write complete messages or Tokens to production logs.
        pass

    listener = im.on(WKIMEvent.MESSAGE, receive)
    im.on(WKIMEvent.ERROR, lambda error: print("EasySDK operation failed"))
    async with im:
        ack = await im.send(
            "bob", WKIMChannelType.PERSON,
            {"type": 1, "content": "Hello from Python!"},
        )
        assert ack["reasonCode"] == 1
        await asyncio.sleep(10)
    im.off(WKIMEvent.MESSAGE, listener)


asyncio.run(main())

async with im waits for CONNECT authentication on entry and calls destroy() on exit. Use WKIMChannelType.GROUP for groups; your backend must establish the Channel and membership first. Payloads accept JSON objects or arrays, encoded as Base64 UTF-8 JSON. Incoming object, JSON-text, and Base64 JSON profiles are supported.

Python parameters use snake_case, while received message and result dictionaries retain JS camelCase. SENDACK includes messageId, messageSeq, and reasonCode; received messages also contain header, channelId, channelType, fromUid, a seconds-based timestamp, and payload. Message IDs are strings and sequences retain full integer precision. WKIMEvent.CUSTOM_EVENT provides id, type, a milliseconds-based timestamp, and data.

send() accepts client_msg_no, header, setting, and topic keyword arguments. header.redDot defaults to true and preserves an explicit false. Optional message flags and Channel types still depend on server support.

Automatic RECVACK means the message entered the SDK dispatcher, not that application processing or reading completed. See messaging for the distinction between send success, peer reception, and business processing.

4. Own the async lifecycle

Each instance belongs to one asyncio event loop; there is no global singleton. Sync and async callbacks run serially on a separate task. Async callbacks may await im.send(...) to reply, disconnect, or destroy the client. Do not block the event loop or wait for a subsequent event on the same serial dispatcher.

OperationContract
await im.connect()Concurrent callers share authentication; connected calls return the current result
im.is_connectedThe current connection is authenticated
im.on(event, callback) / im.off(event, callback)Retain and remove the original callback; an executing callback may finish
await im.ping()Require a matching response ID, including valid result: null
await im.disconnect()Cancel pending requests, socket, heartbeat, and retries; reconnect remains possible
await im.destroy()Permanently close and release listeners; idempotent
Changing account, Token, or URLClose the old instance and create a new one

Cancelling one connect() waiter does not cancel the shared connection; use disconnect() to stop it. Cancelled or timed-out sends release request capacity, but a message that reached the server may still commit.

5. Timeouts, reconnect, and capacity

All WKIMOptions durations are seconds: 10 for the total connection deadline, 15 for requests, 25 between heartbeats, 10 for Pong, and 2 for close. An unexpected transport loss after authentication allows up to 5 retries, exponentially increasing from 1 second to a 30-second cap with 20% jitter. First-connect failure, authentication rejection, server-initiated disconnect, protocol errors, event saturation, certificate verification failure, and manual shutdown stop automatic retry.

Defaults allow 1,024 pending requests, 4 MiB of serialized pending request data, 1 MiB per wire message, and 256 queued events with a 4 MiB wire-size budget including the executing event; Python object overhead is additional. Request saturation returns ErrorCode.QUEUE_FULL. Event saturation closes the connection without acknowledging messages that could not enter the queue; lifecycle notifications are best effort under overload. Keep callbacks short and apply application backpressure.

There is no offline queue or automatic replay. A timeout or lost SENDACK can leave the commit outcome unknown. Retain client_msg_no, reconcile through your backend, then decide whether to retry. WKIMError.code retains the server reason or local ErrorCode; error text does not echo sensitive responses.

6. WSS and validation scope

WSS verifies certificate chains and hostnames by default, with a TLS 1.2 minimum. Use WKIMOptions(ca_file="/path/ca.pem") for a private CA; the interactive example reads WKIM_CA_FILE. There is no verification bypass or automatic system-proxy discovery; supply the reachable Gateway/proxy URL directly.

Logging is off by default. WKIMOptions(debug_logging=True) enables only fixed lifecycle metadata, excluding Tokens, Payloads, URLs, raw frames, peer response text, and underlying exception objects.

PyPI 0.1.0 was published from ec2c62c73eca29be99ac15ba76ff7466c13617d5. The public wheel and sdist SHA-256 values match the publish workflow artifacts. Clean PyPI installations on Python 3.11.12 / websockets 15.0.1 and Python 3.14.7 / websockets 17.1 each passed 64 tests and real Python/Python and JS 2.0.4 bidirectional messaging, Ping, manual reconnect, invalid-Token rejection, and online cleanup against WuKongIM 0348c0539bbee420a859439695acdac911afa854, a Token-authenticated 256-hash-slot single-node cluster. JS was built from pinned source. Independent WS/WSS tests cover automatic retry, cancellation, queue bounds, and certificate rejection. See the PyPI package validation record for exact hashes, installation receipts, versions, and reproduction commands.

A separate three-node WSS acceptance workflow installs the pinned PyPI version and connects through private-CA TLS proxies to three real nodes. It covers cross-node messaging, lost SENDACKs, transport recovery, node restart, Token rotation and cleanup. CI runs a short acceptance; manual runs can select 30 or 60 minutes. Each receipt identifies the package, server, JS and harness separately.

The same PyPI 0.1.0 then completed a 30-minute WSS acceptance against WuKongIM e7ef61ba702e045648b9fa535f051e5b2ee4a1db on a local three-node cluster with 256 hash slots, 12 physical Slots and three Slot replicas, matching 35,380 SENDACK/RECV pairs. Six transport/ACK-loss faults, an ingress node restart and Token rotation on all three nodes passed. No duplicate callbacks were observed; connection/task counts remained stable, with zero owned processes, connections or extra tasks after cleanup. The run uses explicitly configured fault-test deadlines and reconnect limits. See the three-node WSS validation record for versions, resource samples and raw JSON; this is not a production-capacity or exactly-once-delivery guarantee.

Offline sync, conversations, unread counts, and push require the full SDK. Validate your actual WSS proxy, Token rotation, duplicate handling, and capacity, or return to the EasySDK overview and official examples.

7. Online group messaging and permissions

Keep the installed package at wukong-easy-sdk==0.1.0. Groups use the same connection, WKIMChannelType.GROUP (2) and WKIMEvent.MESSAGE; there is no client subscription call:

await im.send("team-chat", WKIMChannelType.GROUP, {"type": 1, "content": "Hello, group"})

A trusted backend first creates the group, adds members, and supplies device-category 2 Tokens. Execute this Product HTTP request only on the trusted server; do not expose management access to untrusted clients. This example adds Alice and Bob and explicitly rejects nonmember sends:

POST /channel
Content-Type: application/json

{"channel_id":"team-chat","channel_type":2,"allow_stranger":0,"reset":1,"subscribers":["alice","bob"]}

reset:1 replaces existing membership, so use it only for a new example group. For subsequent changes, the backend uses /channel/subscriber_add or /channel/subscriber_remove with channel_id, channel_type:2 and subscribers. Blacklist changes use /channel/blacklist_add or /channel/blacklist_remove with uids instead of subscribers.

Download the pinned source containing the new group example; the original v0.1.0 tag predates this file. Example source and the installed PyPI package are pinned separately:

git clone https://github.com/WuKongIM/WuKongEasySDK-Python.git WuKongEasySDK-Python-group
git -C WuKongEasySDK-Python-group checkout --detach 527f37c876326e7ad3cc48c89828c4c3ffed09fc
export WKIM_UID=alice
export WKIM_GROUP=team-chat
# Supply WKIM_TOKEN and WKIM_URL securely; set WKIM_CA_FILE for a private CA.
python WuKongEasySDK-Python-group/examples/group_chat.py

Use Bob's UID and Token with the same group ID in another terminal. Once both members are online, type messages or /quit to exit. The example displays message content and numeric errors. Under the policy above, nonmember sends raise WKIMError.code == 3; blacklist rejection uses code 4. Server policy is authoritative. Check membership and reconcile uncertain send outcomes before retrying. SENDACK is not a read receipt; reconnection does not fetch missed history.

Server requirement: cross-ingress membership acceptance uses fixed server source 2a295e0d9881ef5356728a85d56b052c4b0d9c86. Older servers can retain stale recipients after membership changes through another node; upgrading the Python package cannot correct that server behavior. This record validates fixed source and does not imply that older server installation packages contain the fix.

The group package validation record separately covers three-node WSS, four Python/JS clients, two groups and 13 phases: member fanout, channel isolation, add/remove/readd, nonmember/blacklist rejection, and membership/permissions after all four clients reconnect. Python 3.11 and 3.14 PyPI consumers also execute the real group CLI. Each phase observes excluded clients for one second. This is functional acceptance, not large-group capacity or an exactly-once guarantee. Independent CI candidate-wheel receipts remain separate from PyPI download evidence.

Clients log in after all 12 Slots finish initial preferred-leader convergence, with both topology snapshots recorded. Startup leader changes previously left temporary gaps in online routes; issue #7 retains the diagnosis and failed receipts. The existing server reconstructs presence after an authority change from the next valid client activity. This validation does not guarantee uninterrupted online delivery during Slot leader migration or automatically recover missing messages.

On this page