Python SDK for RealtimeX real-time messaging service
Project description
RealtimeX Python SDK
Python client library for RealtimeX real-time messaging service.
Requirements
- Python 3.7+
python-socketio[client]>= 5.10.0requests(for private channel auth)
Installation
pip
pip install realtimex-python
Quick Start
from realtimex import RealtimeX
# Initialize
realtimex = RealtimeX('YOUR_API_KEY', {
'cluster': 'eu', # optional, default 'eu'
'ws_host': 'ws.realtimex.net', # optional
'ws_port': 443, # optional
'encrypted': True, # optional, default True
})
# Bind connection events
realtimex.connection.bind('connected', lambda: print('Connected!'))
# Connect to server
realtimex.connect()
# Subscribe to a channel
channel = realtimex.subscribe('my-channel')
# Listen for events
channel.bind('my-event', lambda data: print('Received:', data))
# Send client events
channel.trigger('client-my-event', {
'message': 'Hello'
})
API
RealtimeX(api_key, options={})
Create a new RealtimeX instance.
Options:
cluster(str): Cluster name, default'eu'ws_host(str): WebSocket host, default'ws.realtimex.net'ws_port(int): WebSocket port, default443encrypted(bool): Use WSS, defaultTrue
Methods
subscribe(channel_name)
Subscribe to a channel.
channel = realtimex.subscribe('my-channel')
unsubscribe(channel_name)
Unsubscribe from a channel.
realtimex.unsubscribe('my-channel')
disconnect()
Disconnect from RealtimeX.
realtimex.disconnect()
Channel
bind(event, callback)
Bind to an event.
channel.bind('my-event', lambda data: print(data))
unbind(event, callback=None)
Unbind from an event.
channel.unbind('my-event')
trigger(event, data)
Trigger a client event (must be prefixed with client-).
⚠️ Note: Client events only work on private-* and presence-* channels. Public channels will drop client events.
channel.trigger('client-my-event', {'message': 'Hello'})
bind_global(callback)
Bind to all events on the channel.
channel.bind_global(lambda event, data: print(event, data))
Events
Event Flow:
WebSocket Server → SDK Connection → SDK processes → Emits to user code
Example:
Server sends: realtimex_internal:subscription_succeeded
↓
SDK Connection receives and converts to: subscription_succeeded
↓
User binds: realtimex.connection.bind('subscription_succeeded', callback)
1. Connection Events
Events emitted by the connection object:
| Event | Description |
|---|---|
connecting |
Client is attempting to connect |
connected |
Successfully connected, socket_id received |
disconnected |
Connection closed |
Example:
realtimex.connection.bind('connected', lambda: print('Connected!'))
realtimex.connection.bind('disconnected', lambda: print('Disconnected'))
2. Channel Internal Events
Internal RealtimeX events sent by the server (bind on connection object):
| Event | Description |
|---|---|
subscription_succeeded |
Channel subscription successful |
subscription_error |
Channel subscription failed |
Example:
realtimex.connection.bind('subscription_succeeded', lambda data: print('Subscribed:', data))
realtimex.connection.bind('subscription_error', lambda err: print('Error:', err))
Raw Internal Events from Server:
You can also listen to raw internal events sent by the RealtimeX server:
| Event | Description |
|---|---|
realtimex_internal:subscription_succeeded |
Channel subscription successful |
realtimex_internal:subscription_error |
Subscription error |
realtimex_internal:member_added |
New member joined presence channel |
realtimex_internal:member_removed |
Member left presence channel |
Example:
# Listen to raw internal events (advanced usage)
channel.bind('realtimex_internal:subscription_succeeded',
lambda data: print('Raw subscription event:', data))
channel.bind('realtimex_internal:member_added',
lambda member: print('Raw member added:', member))
3. Channel Events
Custom user events sent on channels:
| Event | Description |
|---|---|
| Any string | Events sent by server or other clients |
client-* |
Client events (must be prefixed with client-) |
⚠️ Note: Client events (client-*) only work on private-* and presence-* channels.
Example:
channel.bind('new-message', lambda data: print(data))
channel.bind('user-joined', lambda user: print('User joined:', user))
# Send client event (only works on private/presence channels)
channel.trigger('client-typing', {'user': 'John'})
4. Presence Channel Events
Special events for presence channels:
| Event | Description |
|---|---|
presence:subscription_succeeded |
You joined presence channel |
presence:member_added |
New user added |
presence:member_removed |
User left |
Example:
presence = realtimex.subscribe('presence-chat')
presence.bind('presence:subscription_succeeded',
lambda members: print('Members:', members))
presence.bind('presence:member_added',
lambda member: print('Joined:', member))
presence.bind('presence:member_removed',
lambda member: print('Left:', member))
Public Channels
Public channels work immediately without any backend setup. Just subscribe and start listening!
from realtimex import RealtimeX
realtimex = RealtimeX('YOUR_API_KEY')
realtimex.connect()
# Subscribe to public channel
channel = realtimex.subscribe('my-channel')
# Listen for events
channel.bind('my-event', lambda data: print('Received:', data))
⚠️ Note: Public channels do NOT support client events (client-*). Use private or presence channels for client-to-client messaging.
No backend required! ✅
Private & Presence Channels
⚠️ Requires YOUR backend to generate auth tokens.
Private and presence channels require authentication. The SDK requests auth tokens from YOUR backend, not the RealtimeX server.
⚠️ Important: Where is the auth endpoint?
The auth endpoint MUST be on YOUR backend, NOT on the RealtimeX server.
- ✅ Correct:
auth_endpoint: 'http://localhost:8000/auth'(your Flask/Django/Express server) - ❌ Wrong:
auth_endpoint: 'http://localhost:3001/auth'(RealtimeX WebSocket server)
The SDK NEVER requests auth from the RealtimeX WebSocket server. It only connects to it after getting the auth token from YOUR backend.
┌─────────────┐ HTTP POST ┌──────────────┐
│ Python SDK │ ──────────────────> │ YOUR Backend │
│ │ (get auth token) │ /auth │
└─────────────┘ └──────────────┘
│ │
│ ▼
│ Generate HMAC
│ auth token
│ │
│ auth token │
│ <───────────────────────────────────┘
│
│ WebSocket + auth
└──────────────────────────────────────────>
┌──────────────────┐
│ RealtimeX Server │
│ (validates) │
└──────────────────┘
Authentication Behavior:
- By default:
auth_endpointandauth_callbackareNone→ private channels will throwValueError - Priority:
auth_callbackoverridesauth_endpointif both are provided - Error: If neither is set, SDK raises error when subscribing to
private-*orpresence-*channels
# ❌ This will raise ValueError
realtimex = RealtimeX('API_KEY')
channel = realtimex.subscribe('private-test') # ValueError: auth_callback or auth_endpoint required
# ✅ This works
realtimex = RealtimeX('API_KEY', {'auth_endpoint': 'http://localhost:8000/auth'})
channel = realtimex.subscribe('private-test') # OK
Option 1: With auth_endpoint (automatic):
realtimex = RealtimeX('YOUR_API_KEY', {
'ws_host': 'localhost',
'ws_port': 3001,
'encrypted': False,
'auth_endpoint': 'http://localhost:8000/auth' # YOUR backend auth endpoint
})
realtimex.connect()
channel = realtimex.subscribe('private-my-channel') # SDK requests auth from YOUR backend
Your backend /auth endpoint should:
For Private Channels:
# Example Flask endpoint for private channels
@app.route('/auth', methods=['POST'])
def auth_channel():
data = request.json
socket_id = data['socket_id']
channel_name = data['channel_name']
# Generate HMAC signature
import hmac
import hashlib
string_to_sign = f"{socket_id}:{channel_name}"
auth = hmac.new(
YOUR_APP_SECRET.encode(),
string_to_sign.encode(),
hashlib.sha256
).hexdigest()
return {
'auth': f"{YOUR_APP_KEY}:{auth}"
}
For Presence Channels:
# Example Flask endpoint for presence channels
import json
@app.route('/auth', methods=['POST'])
def auth_channel():
data = request.json
socket_id = data['socket_id']
channel_name = data['channel_name']
# Get user_data from request (sent by SDK)
user_data = data.get('user_data', {})
# Serialize user_data to JSON string
channel_data = json.dumps(user_data)
# Generate HMAC signature with channel_data
import hmac
import hashlib
string_to_sign = f"{socket_id}:{channel_name}:{channel_data}"
auth = hmac.new(
YOUR_APP_SECRET.encode(),
string_to_sign.encode(),
hashlib.sha256
).hexdigest()
return {
'auth': f"{YOUR_APP_KEY}:{auth}",
'channel_data': channel_data
}
Option 2: With custom auth_callback:
import requests
def authorizer(channel_name, socket_id):
# Custom auth logic
response = requests.post('http://localhost:3001/auth/channels', json={
'channel_name': channel_name,
'socket_id': socket_id
})
return response.json() # Returns: {'auth': 'real_token', 'channel_data': '...'}
realtimex = RealtimeX('YOUR_API_KEY',
options={'ws_host': 'localhost', 'ws_port': 3001, 'encrypted': False},
auth_callback=authorizer
)
realtimex.connect()
channel = realtimex.subscribe('private-my-channel')
Presence channels with user data:
realtimex = RealtimeX('YOUR_API_KEY',
options={
'ws_host': 'localhost',
'ws_port': 3001,
'encrypted': False,
'auth_endpoint': 'http://localhost:8000/auth' # YOUR backend
},
user_data={'user_id': '123', 'name': 'John'}
)
realtimex.connect()
channel = realtimex.subscribe('presence-room-1')
Flow:
Python SDK → YOUR Backend /auth → SDK gets auth token → RealtimeX WebSocket → Success
Complete Working Example
Minimal working project with private channel authentication:
1. Install dependencies:
pip install realtimex-python flask
2. Create server.py (your auth backend):
from flask import Flask, request, jsonify
import hmac
import hashlib
import json
app = Flask(__name__)
APP_KEY = 'your_app_key'
APP_SECRET = 'your_app_secret'
@app.route('/auth', methods=['POST'])
def auth():
data = request.json
socket_id = data['socket_id']
channel_name = data['channel_name']
# Check if it's a presence channel
if channel_name.startswith('presence-'):
user_data = data.get('user_data', {})
channel_data = json.dumps(user_data)
string_to_sign = f"{socket_id}:{channel_name}:{channel_data}"
auth_signature = hmac.new(
APP_SECRET.encode(),
string_to_sign.encode(),
hashlib.sha256
).hexdigest()
return jsonify({
'auth': f"{APP_KEY}:{auth_signature}",
'channel_data': channel_data
})
else:
# Private channel
string_to_sign = f"{socket_id}:{channel_name}"
auth_signature = hmac.new(
APP_SECRET.encode(),
string_to_sign.encode(),
hashlib.sha256
).hexdigest()
return jsonify({
'auth': f"{APP_KEY}:{auth_signature}"
})
if __name__ == '__main__':
app.run(port=8000)
3. Create client.py:
from realtimex import RealtimeX
import time
API_KEY = 'your_api_key'
client = RealtimeX(API_KEY, {
'ws_host': 'localhost',
'ws_port': 3001,
'encrypted': False,
'auth_endpoint': 'http://localhost:8000/auth'
})
client.connection.bind('connected', lambda: print('✅ Connected!'))
client.connection.bind('subscription_succeeded', lambda data: print('✅ Subscribed:', data))
client.connect()
# Wait for connection
time.sleep(1)
# Subscribe to private channel
channel = client.subscribe('private-test-channel')
channel.bind('my-event', lambda data: print('📨 Received:', data))
# Keep alive
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
client.disconnect()
print('👋 Disconnected')
4. Run:
# Terminal 1: Start auth server
python3 server.py
# Terminal 2: Start client
python3 client.py
Expected output:
✅ Connected!
✅ Subscribed: {'channel': 'private-test-channel', 'socket_id': '...'}
License
MIT
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file realtimex_python-1.0.5.tar.gz.
File metadata
- Download URL: realtimex_python-1.0.5.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b58e61fe65e8a4d00c6898a0f26a49e8a0c55397c1fae761155424b9b676496
|
|
| MD5 |
727d6bf50ee8453339a04b7ec6846244
|
|
| BLAKE2b-256 |
dd853c44b8905dcb2a6c937dfbed680583e59dbf4a8154b54e88f7dc3caea6f8
|
File details
Details for the file realtimex_python-1.0.5-py3-none-any.whl.
File metadata
- Download URL: realtimex_python-1.0.5-py3-none-any.whl
- Upload date:
- Size: 13.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb6e170e71552d0e71429f22425a1787c87346d81296b7d27d4508b966d38482
|
|
| MD5 |
cb08c61283706d7ee7fff8463d40af66
|
|
| BLAKE2b-256 |
3906dcc58c7db02114e27d70b191cf305a5efbe2551acb26633d256500b574e1
|