Skip to content

Commit be3d06d

Browse files
committed
add ping_interval and ping_timeout params
1 parent 4351159 commit be3d06d

5 files changed

Lines changed: 68 additions & 36 deletions

File tree

README.md

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ A comprehensive Python package to interact with the Mist Cloud APIs, built from
3131
- [Pagination](#pagination-support)
3232
- [Examples](#examples)
3333
- [WebSocket Streaming](#websocket-streaming)
34-
- [Available Channels](#available-channels)
34+
- [Connection Parameters](#connection-parameters)
3535
- [Callbacks](#callbacks)
36+
- [Available Channels](#available-channels)
3637
- [Usage Patterns](#usage-patterns)
3738
- [Development](#development-and-testing)
3839
- [Contributing](#contributing)
@@ -482,6 +483,34 @@ events = mistapi.api.v1.orgs.clients.searchOrgClientsEvents(
482483

483484
The package provides a WebSocket client for real-time event streaming from the Mist API (`wss://{host}/api-ws/v1/stream`). Authentication is handled automatically using the same session credentials (API token or login/password).
484485

486+
### Connection Parameters
487+
488+
All channel classes accept the following optional keyword arguments to control the WebSocket keep-alive behaviour:
489+
490+
| Parameter | Type | Default | Description |
491+
|-----------|------|---------|-------------|
492+
| `ping_interval` | `int` | `30` | Seconds between automatic ping frames. Set to `0` to disable pings. |
493+
| `ping_timeout` | `int` | `10` | Seconds to wait for a pong response before treating the connection as dead. |
494+
495+
```python
496+
ws = mistapi.websockets.sites.SiteDeviceStatsEvents(
497+
apisession,
498+
site_id="<site_id>",
499+
ping_interval=60, # ping every 60 s
500+
ping_timeout=20, # wait up to 20 s for pong
501+
)
502+
ws.connect()
503+
```
504+
505+
### Callbacks
506+
507+
| Method | Signature | Description |
508+
|--------|-----------|-------------|
509+
| `ws.on_open(cb)` | `cb()` | Called when the connection is established |
510+
| `ws.on_message(cb)` | `cb(data: dict)` | Called for every incoming message |
511+
| `ws.on_error(cb)` | `cb(error: Exception)` | Called on WebSocket errors |
512+
| `ws.on_close(cb)` | `cb(status_code: int, msg: str)` | Called when the connection closes |
513+
485514
### Available Channels
486515

487516
#### Organization Channels
@@ -512,15 +541,6 @@ The package provides a WebSocket client for real-time event streaming from the M
512541
| `mistapi.websockets.location.LocationUnconnectedClientsEvents` | `/sites/{site_id}/stats/maps/{map_id}/unconnected_clients` | Real-time unconnected clients location events |
513542
| `mistapi.websockets.location.LocationDiscoveredBleAssetsEvents` | `/sites/{site_id}/stats/maps/{map_id}/discovered_assets` | Real-time discovered BLE assets location events |
514543

515-
### Callbacks
516-
517-
| Method | Signature | Description |
518-
|--------|-----------|-------------|
519-
| `ws.on_open(cb)` | `cb()` | Called when the connection is established |
520-
| `ws.on_message(cb)` | `cb(data: dict)` | Called for every incoming message |
521-
| `ws.on_error(cb)` | `cb(error: Exception)` | Called on WebSocket errors |
522-
| `ws.on_close(cb)` | `cb(status_code: int, msg: str)` | Called when the connection closes |
523-
524544
### Usage Patterns
525545

526546
#### Callback style (recommended)

src/mistapi/websockets/__ws_client.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,17 @@ class _MistWebsocket:
3636
- Login/password sessions pass the requests Session cookies.
3737
"""
3838

39-
def __init__(self, mist_session: "APISession", channel: str) -> None:
39+
def __init__(
40+
self,
41+
mist_session: "APISession",
42+
channel: str,
43+
ping_interval: int = 30,
44+
ping_timeout: int = 10,
45+
) -> None:
4046
self._mist_session = mist_session
4147
self._channel = channel
48+
self._ping_interval = ping_interval
49+
self._ping_timeout = ping_timeout
4250
self._ws: websocket.WebSocketApp | None = None
4351
self._thread: threading.Thread | None = None
4452
self._queue: queue.Queue[dict | None] = queue.Queue()
@@ -147,7 +155,7 @@ def connect(self, run_in_background: bool = True) -> None:
147155
def _run_forever_safe(self) -> None:
148156
if self._ws:
149157
try:
150-
self._ws.run_forever(ping_interval=30, ping_timeout=10)
158+
self._ws.run_forever(ping_interval=self._ping_interval, ping_timeout=self._ping_timeout)
151159
except Exception as exc:
152160
self._handle_error(self._ws, exc)
153161
self._handle_close(self._ws, -1, str(exc))

src/mistapi/websockets/location.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ class LocationBleAssetsEvents(_MistWebsocket):
5454
time.sleep(60)
5555
"""
5656

57-
def __init__(self, mist_session: APISession, site_id: str, map_id: str) -> None:
57+
def __init__(self, mist_session: APISession, site_id: str, map_id: str, **kwargs) -> None:
5858
super().__init__(
59-
mist_session, channel=f"/sites/{site_id}/stats/maps/{map_id}/assets"
59+
mist_session, channel=f"/sites/{site_id}/stats/maps/{map_id}/assets", **kwargs
6060
)
6161

6262

@@ -99,10 +99,11 @@ class LocationConnectedClientsEvents(_MistWebsocket):
9999
time.sleep(60)
100100
"""
101101

102-
def __init__(self, mist_session: APISession, site_id: str, map_id: str) -> None:
102+
def __init__(self, mist_session: APISession, site_id: str, map_id: str, **kwargs) -> None:
103103
super().__init__(
104104
mist_session,
105105
channel=f"/sites/{site_id}/stats/maps/{map_id}/clients",
106+
**kwargs,
106107
)
107108

108109

@@ -145,10 +146,11 @@ class LocationSdkClientsEvents(_MistWebsocket):
145146
time.sleep(60)
146147
"""
147148

148-
def __init__(self, mist_session: APISession, site_id: str, map_id: str) -> None:
149+
def __init__(self, mist_session: APISession, site_id: str, map_id: str, **kwargs) -> None:
149150
super().__init__(
150151
mist_session,
151152
channel=f"/sites/{site_id}/stats/maps/{map_id}/sdkclients",
153+
**kwargs,
152154
)
153155

154156

@@ -191,10 +193,11 @@ class LocationUnconnectedClientsEvents(_MistWebsocket):
191193
time.sleep(60)
192194
"""
193195

194-
def __init__(self, mist_session: APISession, site_id: str, map_id: str) -> None:
196+
def __init__(self, mist_session: APISession, site_id: str, map_id: str, **kwargs) -> None:
195197
super().__init__(
196198
mist_session,
197199
channel=f"/sites/{site_id}/stats/maps/{map_id}/unconnected_clients",
200+
**kwargs,
198201
)
199202

200203

@@ -237,8 +240,9 @@ class LocationDiscoveredBleAssetsEvents(_MistWebsocket):
237240
time.sleep(60)
238241
"""
239242

240-
def __init__(self, mist_session: APISession, site_id: str, map_id: str) -> None:
243+
def __init__(self, mist_session: APISession, site_id: str, map_id: str, **kwargs) -> None:
241244
super().__init__(
242245
mist_session,
243246
channel=f"/sites/{site_id}/stats/maps/{map_id}/discovered_assets",
247+
**kwargs,
244248
)

src/mistapi/websockets/orgs.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ class OrgInsightsEvents(_MistWebsocket):
5252
time.sleep(60)
5353
"""
5454

55-
def __init__(self, mist_session: APISession, org_id: str) -> None:
56-
super().__init__(mist_session, channel=f"/orgs/{org_id}/insights/summary")
55+
def __init__(self, mist_session: APISession, org_id: str, **kwargs) -> None:
56+
super().__init__(mist_session, channel=f"/orgs/{org_id}/insights/summary", **kwargs)
5757

5858

5959
class OrgMxEdgesStatsEvents(_MistWebsocket):
@@ -93,8 +93,8 @@ class OrgMxEdgesStatsEvents(_MistWebsocket):
9393
time.sleep(60)
9494
"""
9595

96-
def __init__(self, mist_session: APISession, org_id: str) -> None:
97-
super().__init__(mist_session, channel=f"/orgs/{org_id}/stats/mxedges")
96+
def __init__(self, mist_session: APISession, org_id: str, **kwargs) -> None:
97+
super().__init__(mist_session, channel=f"/orgs/{org_id}/stats/mxedges", **kwargs)
9898

9999

100100
class OrgMxEdgesUpgradesEvents(_MistWebsocket):
@@ -134,5 +134,5 @@ class OrgMxEdgesUpgradesEvents(_MistWebsocket):
134134
time.sleep(60)
135135
"""
136136

137-
def __init__(self, mist_session: APISession, org_id: str) -> None:
138-
super().__init__(mist_session, channel=f"/orgs/{org_id}/mxedges")
137+
def __init__(self, mist_session: APISession, org_id: str, **kwargs) -> None:
138+
super().__init__(mist_session, channel=f"/orgs/{org_id}/mxedges", **kwargs)

src/mistapi/websockets/sites.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ class SiteClientsStatsEvents(_MistWebsocket):
5252
time.sleep(60)
5353
"""
5454

55-
def __init__(self, mist_session: APISession, site_id: str) -> None:
56-
super().__init__(mist_session, channel=f"/sites/{site_id}/stats/clients")
55+
def __init__(self, mist_session: APISession, site_id: str, **kwargs) -> None:
56+
super().__init__(mist_session, channel=f"/sites/{site_id}/stats/clients", **kwargs)
5757

5858

5959
class SiteDeviceCmdEvents(_MistWebsocket):
@@ -101,9 +101,9 @@ class SiteDeviceCmdEvents(_MistWebsocket):
101101
time.sleep(60)
102102
"""
103103

104-
def __init__(self, mist_session: APISession, site_id: str, device_id: str) -> None:
104+
def __init__(self, mist_session: APISession, site_id: str, device_id: str, **kwargs) -> None:
105105
super().__init__(
106-
mist_session, channel=f"/sites/{site_id}/devices/{device_id}/cmd"
106+
mist_session, channel=f"/sites/{site_id}/devices/{device_id}/cmd", **kwargs
107107
)
108108

109109

@@ -144,8 +144,8 @@ class SiteDeviceStatsEvents(_MistWebsocket):
144144
time.sleep(60)
145145
"""
146146

147-
def __init__(self, mist_session: APISession, site_id: str) -> None:
148-
super().__init__(mist_session, channel=f"/sites/{site_id}/stats/devices")
147+
def __init__(self, mist_session: APISession, site_id: str, **kwargs) -> None:
148+
super().__init__(mist_session, channel=f"/sites/{site_id}/stats/devices", **kwargs)
149149

150150

151151
class SiteDeviceUpgradesEvents(_MistWebsocket):
@@ -185,8 +185,8 @@ class SiteDeviceUpgradesEvents(_MistWebsocket):
185185
time.sleep(60)
186186
"""
187187

188-
def __init__(self, mist_session: APISession, site_id: str) -> None:
189-
super().__init__(mist_session, channel=f"/sites/{site_id}/devices")
188+
def __init__(self, mist_session: APISession, site_id: str, **kwargs) -> None:
189+
super().__init__(mist_session, channel=f"/sites/{site_id}/devices", **kwargs)
190190

191191

192192
class SiteMxEdgesStatsEvents(_MistWebsocket):
@@ -226,8 +226,8 @@ class SiteMxEdgesStatsEvents(_MistWebsocket):
226226
time.sleep(60)
227227
"""
228228

229-
def __init__(self, mist_session: APISession, site_id: str) -> None:
230-
super().__init__(mist_session, channel=f"/sites/{site_id}/stats/mxedges")
229+
def __init__(self, mist_session: APISession, site_id: str, **kwargs) -> None:
230+
super().__init__(mist_session, channel=f"/sites/{site_id}/stats/mxedges", **kwargs)
231231

232232

233233
class SitePcapEvents(_MistWebsocket):
@@ -267,5 +267,5 @@ class SitePcapEvents(_MistWebsocket):
267267
time.sleep(60)
268268
"""
269269

270-
def __init__(self, mist_session: APISession, site_id: str) -> None:
271-
super().__init__(mist_session, channel=f"/sites/{site_id}/pcap")
270+
def __init__(self, mist_session: APISession, site_id: str, **kwargs) -> None:
271+
super().__init__(mist_session, channel=f"/sites/{site_id}/pcap", **kwargs)

0 commit comments

Comments
 (0)