Official async SDK for the Radion platform
Project description
radion-sdk
Official, async-first, fully-typed SDK for the Radion platform.
One client, one API key, every Radion product surface. Install radion-sdk; import it as radion.
radion = Radion(api_key=os.getenv("RADION_API_KEY"))
await radion.realtime.connect()
await radion.realtime.subscribe(Subscription(id="trades", channel="trades"))
@radion.realtime.on_channel("trades")
async def handle_trade(event):
print(event.id, event.data)
Features
- Unified client —
Radion(api_key=...)is the single entry point for every product surface - Auto-reconnect — exponential backoff with jitter; stops on graceful shutdown
- Subscription restore — active channels are re-subscribed after every reconnect
- Heartbeats — ping/pong keep-alive that detects stale connections and reconnects
- Typed end-to-end — channel names, frame models, and errors
- Async-first — built on
asyncio; handlers may be sync or async
Requirements
- Python >= 3.10
Install
uv add radion-sdk
# or: pip install radion-sdk
Quick start
import asyncio
import os
from radion import Radion, Subscription
async def main() -> None:
radion = Radion(api_key=os.getenv("RADION_API_KEY"))
await radion.realtime.connect()
await radion.realtime.subscribe(Subscription(id="trades", channel="trades"))
@radion.realtime.on_channel("trades")
async def handle_trade(event):
print(event.id, event.channel, event.data)
await asyncio.sleep(60)
await radion.realtime.close()
asyncio.run(main())
Usage
Configuration
Radion(api_key, *, base_url=..., ws_url=..., reconnect=True, heartbeat=True,
heartbeat_interval=15.0, heartbeat_timeout=10.0)
| Argument | Type | Default | Description |
|---|---|---|---|
api_key |
str |
— | Required. Sent as the X-API-Key header. |
base_url |
str |
https://api.radion.app |
Base URL for the Radion API. |
ws_url |
str |
wss://api.radion.app/ws |
Override the realtime endpoint. |
reconnect |
bool |
True |
Auto-reconnect on unexpected disconnect. |
heartbeat |
bool |
True |
Enable heartbeats / stale detection. |
heartbeat_interval |
float |
15.0 |
Seconds between pings. |
heartbeat_timeout |
float |
10.0 |
Extra grace before a quiet connection is stale. |
Extra keyword arguments are forwarded to the realtime client.
Realtime client
radion.realtime is a RealtimeClient. It can also be imported and
constructed standalone:
from radion import RealtimeClient
client = RealtimeClient(api_key=os.getenv("RADION_API_KEY"))
| Method | Description |
|---|---|
await connect() |
Open the connection. Resolves once established. |
await subscribe(subscription) |
Subscribe with Subscription(id, channel, filters). Replayed on reconnect. |
await unsubscribe(id) |
Unsubscribe by subscription id. |
on_channel(channel) |
Decorator for a specific channel handler (incl. mempool. channels). |
off_channel(channel, handler=None) |
Remove a channel handler (or all for that channel). |
on_any_channel() |
Decorator for a wildcard handler — every channel event. |
off_any_channel(handler=None) |
Remove a wildcard handler (or all of them). |
on_lifecycle(event) |
Decorator for a lifecycle handler: open, close, reconnect, error. |
off_lifecycle(event, handler=None) |
Remove a lifecycle handler (or all for that event). |
await close(code=1000, ...) |
Graceful shutdown. Stops reconnect attempts. |
connected |
Property — whether the socket is currently open. |
Subscriptions & filters
A subscription is Subscription(id, channel, filters=None). The id is your
own string, echoed back on every event so you can tell subscriptions apart;
channel may carry a mempool. prefix. Some channels require a filter:
from radion import ChannelFilters, Subscription
await radion.realtime.subscribe(
Subscription(id="whales", channel="large_trades", filters=ChannelFilters(min_usd=10_000))
)
# on_any_channel fires for every channel; the event carries id + channel + data.
@radion.realtime.on_any_channel()
async def on_any(event):
print(event.id, event.channel, event.data)
ChannelFilters: wallets, market_ids, token_ids, min_usd.
Channels
global · trades · activity · lifecycle · oracle · collateral
combos · prices · wallets · markets · large_trades
Available as the CHANNELS tuple and the Channel type.
from radion import CHANNELS, Subscription
for channel in CHANNELS:
await radion.realtime.subscribe(Subscription(id=channel, channel=channel))
Lifecycle events
@radion.realtime.on_lifecycle("open")
async def opened(_):
print("connected")
@radion.realtime.on_lifecycle("close")
async def closed(info):
print(info["code"], info["reason"])
@radion.realtime.on_lifecycle("reconnect")
async def reconnecting(info):
print(info["attempt"], info["delay"])
@radion.realtime.on_lifecycle("error")
async def errored(err):
print(err)
Reconnect & subscription restore
On an unexpected disconnect the client reconnects with exponential backoff and
re-sends every active subscription once the socket reopens. After close() no
further attempts run.
Heartbeats
A ping is sent every heartbeat_interval seconds. Any inbound frame counts as
liveness; if the connection goes quiet past the timeout window it is terminated
and reconnected.
Error handling
from radion import RadionConnectionError, RadionServerError
@radion.realtime.on_lifecycle("error")
async def errored(err):
if isinstance(err, RadionServerError):
print("server error", err.code, err.channel)
elif isinstance(err, RadionConnectionError):
print("connection error", err)
A throwing consumer handler is reported via the error event and never retried.
License
MIT
Project details
Release history Release notifications | RSS feed
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 radion_sdk-0.3.0.tar.gz.
File metadata
- Download URL: radion_sdk-0.3.0.tar.gz
- Upload date:
- Size: 30.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4781b8a589610693be7a2434fd90834f0b6221b2fb1865ae4b749407288c88a
|
|
| MD5 |
e34cac872d900d688d60593b0e5c7c9d
|
|
| BLAKE2b-256 |
42d7f9c67b18cc221b3d3db72d8bfdc6800edc724ed0425ce66596223c56866b
|
File details
Details for the file radion_sdk-0.3.0-py3-none-any.whl.
File metadata
- Download URL: radion_sdk-0.3.0-py3-none-any.whl
- Upload date:
- Size: 19.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6deb7626ccaeba32d2f0626c9eefdea6fe2a58f9e481e07c0c47fe1826ef505f
|
|
| MD5 |
ab10e2abe64fbc9980235c4656c10522
|
|
| BLAKE2b-256 |
c51dab8f838fef2d26220fa0dd0693efbc1ad2c84cf0575fee9d7c3b96746ed2
|