Skip to main content

Python SDK for OpenIM-style login, messaging, and websocket sync.

Project description

openim_sdk

Python SDK for OpenIM-style login, send message, and receive message.

Modes

  • OpenIMWSSDK (recommended): websocket direct connection (gob + gzip + protobuf) with heartbeat and auto reconnect.
  • OpenIMSDK: HTTP polling fallback.

WebSocket quick start

from openim_sdk import OpenIMWSSDK, WSConfig

sdk = OpenIMWSSDK(
    WSConfig(ws_addr="ws://127.0.0.1:10001/msg_gateway", data_dir="./openim_py_data")
)
sdk.login(user_id="u1", token="YOUR_TOKEN")
sdk.start()
sdk.send_text("hello", recv_id="u2")

See openim_sdk/example_ws.py for a runnable demo script.

WebSocket detailed usage

1. Build config

WSConfig parameters:

  • ws_addr (required): websocket gateway address, e.g. ws://127.0.0.1:10001/msg_gateway
  • api_addr: HTTP API address for profile fetch (used to cache self info for send), e.g. http://127.0.0.1:10002; when empty, sdk falls back to env OPENIM_API_ADDR
  • data_dir: local sqlite directory, default ./data
  • platform_id: platform ID sent to server, default 1
  • timeout_seconds: request/response wait timeout, default 1000
  • pull_batch_size: sync page size, default 100
  • sdk_version: value sent in ws query, default python-ws-0.1.0
  • auto_sync_on_connect: run sync_once() immediately after first connect, default False
  • auto_sync_on_reconnect: auto sync after reconnect, default True
  • auto_reconnect: reconnect automatically on disconnect, default True
  • max_reconnect_attempts: reconnect attempt cap, default 300
  • reconnect_backoff_seconds: reconnect interval sequence, default (1, 2, 4, 8, 16)
  • enable_heartbeat: send ws ping periodically, default True
  • heartbeat_interval_seconds: ping interval, default 24
  • heartbeat_pong_timeout_seconds: pong timeout, default 30
  • self_user_info_cache_ttl_seconds: in-memory cache ttl for self profile (senderNickname/senderFaceURL), default 600 seconds

2. Register callbacks

Available callbacks in OpenIMWSSDK(...):

  • on_recv_new_message(msg: WSMessage): called for online real-time messages
  • on_recv_offline_new_message(msg: WSMessage): called for offline/sync messages
  • on_connecting(): called before connect/reconnect attempts
  • on_connect_success(): called after successful connect/reconnect
  • on_connect_failed(exc): called when one connect attempt fails
  • on_kicked_offline(): called when server returns kick event
  • on_error(exc): called on internal errors (decode/send/read/reconnect, etc.)
  • logger(text): sdk log output callback

2.1 WSMessage fields

Raw payload keys:

  • conversationID: conversation id (sdk adds this key)
  • sendID, recvID, groupID
  • clientMsgID, serverMsgID
  • senderPlatformID, senderNickname, senderFaceURL
  • sessionType (1 single, 2 group, 3 super group)
  • msgFrom, contentType, content
  • seq, sendTime, createTime
  • status, isRead
  • options (dict[str, bool])
  • offlinePushInfo (dict)
  • atUserIDList (list[str])
  • attachedInfo, ex

Python field names in WSMessage:

  • conversation_id, send_id, recv_id, group_id
  • client_msg_id, server_msg_id
  • sender_platform_id, sender_nickname, sender_face_url
  • session_type, msg_from, content_type, content
  • seq, send_time, create_time, status, is_read
  • options, offline_push_info, at_user_id_list, attached_info, ex
  • raw: original dictionary payload
  • content_json: parsed JSON from content (or None when not valid JSON)
  • content_obj: typed content object parsed by content_type

content_type -> content_obj mapping (same as sdk_struct.go):

  • 101 -> TextElem
  • 102 -> PictureElem
  • 103 -> SoundElem
  • 104 -> VideoElem
  • 105 -> FileElem
  • 106 -> AtTextElem
  • 107 -> MergeElem
  • 108 -> CardElem
  • 109 -> LocationElem
  • 110/119/120 -> CustomElem
  • 113 -> TypingElem
  • 114 -> QuoteElem
  • 115 -> FaceElem
  • 117 -> AdvancedTextElem
  • 118 -> MarkdownTextElem
  • other content types -> NotificationElem

Minimal callback example:

from openim_sdk import OpenIMWSSDK, WSConfig, WSMessage, TextElem, PictureElem


def on_new_model(msg: WSMessage) -> None:
    if isinstance(msg.content_obj, TextElem):
        print("[text]", msg.content_obj.content)
    elif isinstance(msg.content_obj, PictureElem):
        print("[picture]", msg.content_obj.source_picture)
    else:
        print("[other]", msg.content_type, msg.content_obj)


sdk = OpenIMWSSDK(
    WSConfig(ws_addr="ws://127.0.0.1:10001/msg_gateway"),
    on_recv_new_message=on_new_model,
)

3. Full example (recommended pattern)

import time

from openim_sdk import OpenIMWSSDK, TextElem, WSConfig, WSSDKError, WSMessage


def on_new(msg: WSMessage) -> None:
    if isinstance(msg.content_obj, TextElem):
        print("[new text]", msg.send_id, "->", msg.recv_id, msg.content_obj.content)
    else:
        print("[new]", msg.send_id, "->", msg.recv_id, msg.content_type, msg.content_obj)


def on_offline(msg: WSMessage) -> None:
    print("[offline]", msg.client_msg_id, msg.seq)


def on_err(exc: Exception) -> None:
    print("[error]", exc)


sdk = OpenIMWSSDK(
    WSConfig(
        ws_addr="ws://127.0.0.1:10001/msg_gateway",
        api_addr="http://127.0.0.1:10002",
        data_dir="./openim_py_data",
        auto_sync_on_connect=True,
        auto_sync_on_reconnect=True,
    ),
    on_recv_new_message=on_new,
    on_recv_offline_new_message=on_offline,
    on_connecting=lambda: print("[ws] connecting"),
    on_connect_success=lambda: print("[ws] connected"),
    on_connect_failed=lambda e: print("[ws] connect failed:", e),
    on_kicked_offline=lambda: print("[ws] kicked offline"),
    on_error=on_err,
    logger=lambda s: print("[sdk]", s),
)

try:
    # 1) login first
    sdk.login(user_id="u1", token="YOUR_TOKEN")
    # 2) then start websocket threads
    sdk.start()

    # send peer message
    ack = sdk.send_text("hello from ws sdk", recv_id="u2")
    print("send ack:", ack)  # {"serverMsgID": "...", "clientMsgID": "...", "sendTime": ...}

    # keep process alive
    while True:
        time.sleep(1)
except WSSDKError as e:
    print("business error:", e.err_code, e.err_msg)
except KeyboardInterrupt:
    pass
finally:
    # stop background threads and close db
    sdk.logout()

4. Sending messages

  • Single chat:
sdk.send_text("hello", recv_id="u2")
  • Group chat:
sdk.send_text("hello group", group_id="g123", session_type=2)

send_text(...) notes:

  • must pass one of recv_id or group_id
  • session_type defaults to single chat (1) if recv_id is set, otherwise group (2)
  • if WSConfig.api_addr is set, sdk fetches self profile (/user/get_users_info) and caches it in memory (ttl controlled by self_user_info_cache_ttl_seconds, default 10 minutes), then auto-fills senderNickname and senderFaceURL on send
  • supported session values:
    • 1: single chat
    • 2: group chat
    • 3: super group chat

5. Manual sync

If you want explicit control (instead of auto_sync_on_connect/reconnect), call:

sdk.sync_once()

This pulls missing seq ranges and dispatches them through on_recv_offline_new_message.

6. Lifecycle and best practices

  • call order should be: login(...) -> start() -> send/recv -> logout()
  • stop() only stops ws threads; logout() stops threads and closes local storage
  • keep your process alive after start(), otherwise daemon threads exit with process
  • for production:
    • keep auto_reconnect=True
    • keep heartbeat enabled
    • handle on_error and on_connect_failed for observability/retry alerts
    • persist your own app-level offsets/state if required

HTTP polling quick start

from openim_sdk import OpenIMSDK, SDKConfig

sdk = OpenIMSDK(
    SDKConfig(api_addr="http://127.0.0.1:10002", data_dir="./openim_py_data")
)
sdk.login(user_id="u1", token="YOUR_TOKEN")
sdk.start_receiving()
sdk.send_text("hello", recv_id="u2")
me = sdk.get_self_user_info()
print(me.user_id, me.nickname, me.face_url)

WebSocket features

  • Login with user_id + token
  • Send text message with protobuf payload (MsgData)
  • Receive PushMessages from ws binary frames
  • Gob encode/decode for GeneralWsReq/GeneralWsResp
  • Gzip frame compression/decompression
  • Heartbeat (ping/pong)
  • Auto reconnect with backoff (1,2,4,8,16 seconds loop by default)
  • Auto sync missed messages on connect/reconnect
  • Local SQLite persistence:
    • message rows
    • per-conversation latest synced seq

Local database

  • WS mode: <data_dir>/OpenIM_pyws_<user_id>.db
  • HTTP mode: <data_dir>/OpenIM_py_<user_id>.db

Tables:

  • conversation_seq(conversation_id, last_seq)
  • messages(...)

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

openim_sdk_core-0.1.3.tar.gz (42.0 kB view details)

Uploaded Source

Built Distribution

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

openim_sdk_core-0.1.3-py3-none-any.whl (44.1 kB view details)

Uploaded Python 3

File details

Details for the file openim_sdk_core-0.1.3.tar.gz.

File metadata

  • Download URL: openim_sdk_core-0.1.3.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for openim_sdk_core-0.1.3.tar.gz
Algorithm Hash digest
SHA256 48fe3ef5f65ef69958754f505f73bd4be5d7b9a0a709b7e04cdda00672e49ebf
MD5 3e47d4618c06b668c6d2631a0f487632
BLAKE2b-256 ee40d0de6d6987c30e63d5eab9da28936de01ef855c4f019708d6d87f3816b6e

See more details on using hashes here.

File details

Details for the file openim_sdk_core-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for openim_sdk_core-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 8c05538d9f26e28b77a5f3fd4ea7a6d083c9beba2d7e800ec1760ba405e6dc03
MD5 1fe342c3bf98dfb7ed3c02b1929ae3f6
BLAKE2b-256 4854d9e4459314e6fcdbbeb2a9413e97d9a90e1f309b3f4f3d9f8dbe963d66f1

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