foxglove-sdk 0.14.1__cp312-cp312-musllinux_1_2_i686.whl → 0.16.6__cp312-cp312-musllinux_1_2_i686.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- foxglove/__init__.py +164 -52
- foxglove/_foxglove_py/__init__.pyi +94 -32
- foxglove/_foxglove_py/channels.pyi +396 -330
- foxglove/_foxglove_py/cloud.pyi +9 -0
- foxglove/_foxglove_py/mcap.pyi +53 -12
- foxglove/_foxglove_py/schemas.pyi +311 -318
- foxglove/_foxglove_py/schemas_wkt.pyi +8 -9
- foxglove/_foxglove_py/websocket.pyi +120 -76
- foxglove/_foxglove_py.cpython-312-i386-linux-musl.so +0 -0
- foxglove/channel.py +24 -22
- foxglove/channels/__init__.py +2 -0
- foxglove/cloud.py +61 -0
- foxglove/layouts/__init__.py +17 -0
- foxglove/notebook/__init__.py +0 -0
- foxglove/notebook/foxglove_widget.py +82 -0
- foxglove/notebook/notebook_buffer.py +114 -0
- foxglove/notebook/static/widget.js +1 -0
- foxglove/schemas/__init__.py +3 -0
- foxglove/tests/test_context.py +10 -0
- foxglove/tests/test_logging.py +46 -0
- foxglove/tests/test_mcap.py +363 -2
- foxglove/tests/test_server.py +33 -2
- foxglove/websocket.py +40 -18
- foxglove.libs/libgcc_s-8c2f5de4.so.1 +0 -0
- foxglove_sdk-0.16.6.dist-info/METADATA +53 -0
- foxglove_sdk-0.16.6.dist-info/RECORD +35 -0
- {foxglove_sdk-0.14.1.dist-info → foxglove_sdk-0.16.6.dist-info}/WHEEL +1 -1
- foxglove.libs/libgcc_s-27e5a392.so.1 +0 -0
- foxglove_sdk-0.14.1.dist-info/METADATA +0 -29
- foxglove_sdk-0.14.1.dist-info/RECORD +0 -27
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import datetime
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
class Duration:
|
|
5
4
|
"""
|
|
6
5
|
A duration in seconds and nanoseconds
|
|
7
6
|
"""
|
|
8
7
|
|
|
9
|
-
def
|
|
10
|
-
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
11
10
|
sec: int,
|
|
12
|
-
nsec:
|
|
13
|
-
) ->
|
|
11
|
+
nsec: int | None = None,
|
|
12
|
+
) -> None: ...
|
|
14
13
|
@property
|
|
15
14
|
def sec(self) -> int: ...
|
|
16
15
|
@property
|
|
@@ -42,11 +41,11 @@ class Timestamp:
|
|
|
42
41
|
A timestamp in seconds and nanoseconds
|
|
43
42
|
"""
|
|
44
43
|
|
|
45
|
-
def
|
|
46
|
-
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
47
46
|
sec: int,
|
|
48
|
-
nsec:
|
|
49
|
-
) ->
|
|
47
|
+
nsec: int | None = None,
|
|
48
|
+
) -> None: ...
|
|
50
49
|
@property
|
|
51
50
|
def sec(self) -> int: ...
|
|
52
51
|
@property
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
1
|
from enum import Enum
|
|
3
|
-
from typing import Dict, List, Optional, Union
|
|
4
2
|
|
|
5
|
-
import
|
|
3
|
+
from foxglove import Schema
|
|
4
|
+
from foxglove.websocket import (
|
|
5
|
+
AnyNativeParameterValue,
|
|
6
|
+
AnyParameterValue,
|
|
7
|
+
ServiceHandler,
|
|
8
|
+
)
|
|
6
9
|
|
|
7
10
|
class Capability(Enum):
|
|
8
11
|
"""
|
|
@@ -12,7 +15,7 @@ class Capability(Enum):
|
|
|
12
15
|
ClientPublish = ...
|
|
13
16
|
"""Allow clients to advertise channels to send data messages to the server."""
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
ConnectionGraph = ...
|
|
16
19
|
"""Allow clients to subscribe and make connection graph updates"""
|
|
17
20
|
|
|
18
21
|
Parameters = ...
|
|
@@ -24,6 +27,9 @@ class Capability(Enum):
|
|
|
24
27
|
Time = ...
|
|
25
28
|
"""Inform clients about the latest server time."""
|
|
26
29
|
|
|
30
|
+
RangedPlayback = ...
|
|
31
|
+
"""Indicates that the server is sending data within a fixed time range."""
|
|
32
|
+
|
|
27
33
|
class Client:
|
|
28
34
|
"""
|
|
29
35
|
A client that is connected to a running websocket server.
|
|
@@ -48,16 +54,16 @@ class ClientChannel:
|
|
|
48
54
|
topic: str = ...
|
|
49
55
|
encoding: str = ...
|
|
50
56
|
schema_name: str = ...
|
|
51
|
-
schema_encoding:
|
|
52
|
-
schema:
|
|
57
|
+
schema_encoding: str | None = ...
|
|
58
|
+
schema: bytes | None = ...
|
|
53
59
|
|
|
54
60
|
class ConnectionGraph:
|
|
55
61
|
"""
|
|
56
62
|
A graph of connections between clients.
|
|
57
63
|
"""
|
|
58
64
|
|
|
59
|
-
def
|
|
60
|
-
def set_published_topic(self, topic: str, publisher_ids:
|
|
65
|
+
def __init__(self) -> None: ...
|
|
66
|
+
def set_published_topic(self, topic: str, publisher_ids: list[str]) -> None:
|
|
61
67
|
"""
|
|
62
68
|
Set a published topic and its associated publisher ids. Overwrites any existing topic with
|
|
63
69
|
the same name.
|
|
@@ -67,7 +73,7 @@ class ConnectionGraph:
|
|
|
67
73
|
"""
|
|
68
74
|
...
|
|
69
75
|
|
|
70
|
-
def set_subscribed_topic(self, topic: str, subscriber_ids:
|
|
76
|
+
def set_subscribed_topic(self, topic: str, subscriber_ids: list[str]) -> None:
|
|
71
77
|
"""
|
|
72
78
|
Set a subscribed topic and its associated subscriber ids. Overwrites any existing topic with
|
|
73
79
|
the same name.
|
|
@@ -77,7 +83,7 @@ class ConnectionGraph:
|
|
|
77
83
|
"""
|
|
78
84
|
...
|
|
79
85
|
|
|
80
|
-
def set_advertised_service(self, service: str, provider_ids:
|
|
86
|
+
def set_advertised_service(self, service: str, provider_ids: list[str]) -> None:
|
|
81
87
|
"""
|
|
82
88
|
Set an advertised service and its associated provider ids Overwrites any existing service
|
|
83
89
|
with the same name.
|
|
@@ -93,14 +99,14 @@ class MessageSchema:
|
|
|
93
99
|
"""
|
|
94
100
|
|
|
95
101
|
encoding: str
|
|
96
|
-
schema:
|
|
102
|
+
schema: Schema
|
|
97
103
|
|
|
98
|
-
def
|
|
99
|
-
|
|
104
|
+
def __init__(
|
|
105
|
+
self,
|
|
100
106
|
*,
|
|
101
107
|
encoding: str,
|
|
102
|
-
schema:
|
|
103
|
-
) ->
|
|
108
|
+
schema: Schema,
|
|
109
|
+
) -> None: ...
|
|
104
110
|
|
|
105
111
|
class Parameter:
|
|
106
112
|
"""
|
|
@@ -116,17 +122,17 @@ class Parameter:
|
|
|
116
122
|
"""
|
|
117
123
|
|
|
118
124
|
name: str
|
|
119
|
-
type:
|
|
120
|
-
value:
|
|
125
|
+
type: ParameterType | None
|
|
126
|
+
value: AnyParameterValue | None
|
|
121
127
|
|
|
122
128
|
def __init__(
|
|
123
129
|
self,
|
|
124
130
|
name: str,
|
|
125
131
|
*,
|
|
126
|
-
value:
|
|
127
|
-
type:
|
|
132
|
+
value: AnyNativeParameterValue | None = None,
|
|
133
|
+
type: ParameterType | None = None,
|
|
128
134
|
) -> None: ...
|
|
129
|
-
def get_value(self) ->
|
|
135
|
+
def get_value(self) -> AnyNativeParameterValue | None:
|
|
130
136
|
"""Returns the parameter value as a native python object."""
|
|
131
137
|
...
|
|
132
138
|
|
|
@@ -152,17 +158,17 @@ class ParameterValue:
|
|
|
152
158
|
class Integer:
|
|
153
159
|
"""An integer value."""
|
|
154
160
|
|
|
155
|
-
def
|
|
161
|
+
def __init__(self, value: int) -> None: ...
|
|
156
162
|
|
|
157
163
|
class Bool:
|
|
158
164
|
"""A boolean value."""
|
|
159
165
|
|
|
160
|
-
def
|
|
166
|
+
def __init__(self, value: bool) -> None: ...
|
|
161
167
|
|
|
162
168
|
class Float64:
|
|
163
169
|
"""A floating-point value."""
|
|
164
170
|
|
|
165
|
-
def
|
|
171
|
+
def __init__(self, value: float) -> None: ...
|
|
166
172
|
|
|
167
173
|
class String:
|
|
168
174
|
"""
|
|
@@ -172,47 +178,81 @@ class ParameterValue:
|
|
|
172
178
|
base64 encoding of the byte array.
|
|
173
179
|
"""
|
|
174
180
|
|
|
175
|
-
def
|
|
181
|
+
def __init__(self, value: str) -> None: ...
|
|
176
182
|
|
|
177
183
|
class Array:
|
|
178
184
|
"""An array of parameter values."""
|
|
179
185
|
|
|
180
|
-
def
|
|
181
|
-
cls, value: List["AnyParameterValue"]
|
|
182
|
-
) -> "ParameterValue.Array": ...
|
|
186
|
+
def __init__(self, value: list[AnyParameterValue]) -> None: ...
|
|
183
187
|
|
|
184
188
|
class Dict:
|
|
185
189
|
"""An associative map of parameter values."""
|
|
186
190
|
|
|
187
|
-
def
|
|
188
|
-
cls, value: dict[str, "AnyParameterValue"]
|
|
189
|
-
) -> "ParameterValue.Dict": ...
|
|
191
|
+
def __init__(self, value: dict[str, AnyParameterValue]) -> None: ...
|
|
190
192
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
ParameterValue.Bool,
|
|
194
|
-
ParameterValue.Float64,
|
|
195
|
-
ParameterValue.String,
|
|
196
|
-
ParameterValue.Array,
|
|
197
|
-
ParameterValue.Dict,
|
|
198
|
-
]
|
|
193
|
+
class PlaybackCommand(Enum):
|
|
194
|
+
"""The command for playback requested by the client player"""
|
|
199
195
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
196
|
+
Play = ...
|
|
197
|
+
Pause = ...
|
|
198
|
+
|
|
199
|
+
class PlaybackControlRequest:
|
|
200
|
+
"""
|
|
201
|
+
A request to control playback from the client
|
|
202
|
+
|
|
203
|
+
:param playback_command: The command for playback requested by the client player
|
|
204
|
+
:type playback_command: PlaybackCommand
|
|
205
|
+
:param playback_speed: The speed of playback requested by the client player
|
|
206
|
+
:type playback_speed: float
|
|
207
|
+
:param seek_time: The time the client player is requesting to seek to, in nanoseconds. None if no seek is requested.
|
|
208
|
+
:type seek_time: int | None
|
|
209
|
+
:param request_id: Unique string identifier, used to indicate that a PlaybackState is in response to a particular request from the client.
|
|
210
|
+
:type request_id: str
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
playback_command: PlaybackCommand
|
|
214
|
+
playback_speed: float
|
|
215
|
+
seek_time: int | None
|
|
216
|
+
request_id: str
|
|
217
|
+
|
|
218
|
+
class PlaybackState:
|
|
219
|
+
"""
|
|
220
|
+
The state of data playback on the server
|
|
221
|
+
|
|
222
|
+
:param status: The status of server data playback
|
|
223
|
+
:type status: PlaybackStatus
|
|
224
|
+
:param current_time: The current time of playback, in absolute nanoseconds
|
|
225
|
+
:type current_time: int
|
|
226
|
+
:param playback_speed: The speed of playback, as a factor of realtime
|
|
227
|
+
:type playback_speed: float
|
|
228
|
+
:param did_seek: Whether a seek forward or backward in time triggered this message to be emitted
|
|
229
|
+
:type did_seek: bool
|
|
230
|
+
:param request_id: If this message is being emitted in response to a PlaybackControlRequest message, the request_id from that message. Set this to an empty string if the state of playback has been changed by any other condition.
|
|
231
|
+
:type request_id: str | None
|
|
232
|
+
"""
|
|
209
233
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
234
|
+
status: PlaybackStatus
|
|
235
|
+
current_time: int
|
|
236
|
+
playback_speed: float
|
|
237
|
+
did_seek: bool
|
|
238
|
+
request_id: str | None
|
|
214
239
|
|
|
215
|
-
|
|
240
|
+
def __init__(
|
|
241
|
+
self,
|
|
242
|
+
status: PlaybackStatus,
|
|
243
|
+
current_time: int,
|
|
244
|
+
playback_speed: float,
|
|
245
|
+
did_seek: bool,
|
|
246
|
+
request_id: str | None,
|
|
247
|
+
): ...
|
|
248
|
+
|
|
249
|
+
class PlaybackStatus(Enum):
|
|
250
|
+
"""The status of server data playback"""
|
|
251
|
+
|
|
252
|
+
Playing = ...
|
|
253
|
+
Paused = ...
|
|
254
|
+
Buffering = ...
|
|
255
|
+
Ended = ...
|
|
216
256
|
|
|
217
257
|
class ServiceRequest:
|
|
218
258
|
"""
|
|
@@ -225,24 +265,22 @@ class ServiceRequest:
|
|
|
225
265
|
encoding: str
|
|
226
266
|
payload: bytes
|
|
227
267
|
|
|
228
|
-
ServiceHandler = Callable[["ServiceRequest"], bytes]
|
|
229
|
-
|
|
230
268
|
class Service:
|
|
231
269
|
"""
|
|
232
270
|
A websocket service.
|
|
233
271
|
"""
|
|
234
272
|
|
|
235
273
|
name: str
|
|
236
|
-
schema:
|
|
237
|
-
handler:
|
|
274
|
+
schema: ServiceSchema
|
|
275
|
+
handler: ServiceHandler
|
|
238
276
|
|
|
239
|
-
def
|
|
240
|
-
|
|
277
|
+
def __init__(
|
|
278
|
+
self,
|
|
241
279
|
*,
|
|
242
280
|
name: str,
|
|
243
|
-
schema:
|
|
244
|
-
handler:
|
|
245
|
-
)
|
|
281
|
+
schema: ServiceSchema,
|
|
282
|
+
handler: ServiceHandler,
|
|
283
|
+
): ...
|
|
246
284
|
|
|
247
285
|
class ServiceSchema:
|
|
248
286
|
"""
|
|
@@ -250,16 +288,16 @@ class ServiceSchema:
|
|
|
250
288
|
"""
|
|
251
289
|
|
|
252
290
|
name: str
|
|
253
|
-
request:
|
|
254
|
-
response:
|
|
291
|
+
request: MessageSchema | None
|
|
292
|
+
response: MessageSchema | None
|
|
255
293
|
|
|
256
|
-
def
|
|
257
|
-
|
|
294
|
+
def __init__(
|
|
295
|
+
self,
|
|
258
296
|
*,
|
|
259
297
|
name: str,
|
|
260
|
-
request:
|
|
261
|
-
response:
|
|
262
|
-
)
|
|
298
|
+
request: MessageSchema | None = None,
|
|
299
|
+
response: MessageSchema | None = None,
|
|
300
|
+
): ...
|
|
263
301
|
|
|
264
302
|
class StatusLevel(Enum):
|
|
265
303
|
"""A level for `WebSocketServer.publish_status`"""
|
|
@@ -273,7 +311,7 @@ class WebSocketServer:
|
|
|
273
311
|
A websocket server for live visualization.
|
|
274
312
|
"""
|
|
275
313
|
|
|
276
|
-
def
|
|
314
|
+
def __init__(self) -> None: ...
|
|
277
315
|
@property
|
|
278
316
|
def port(self) -> int:
|
|
279
317
|
"""Get the port on which the server is listening."""
|
|
@@ -282,9 +320,9 @@ class WebSocketServer:
|
|
|
282
320
|
def app_url(
|
|
283
321
|
self,
|
|
284
322
|
*,
|
|
285
|
-
layout_id:
|
|
323
|
+
layout_id: str | None = None,
|
|
286
324
|
open_in_desktop: bool = False,
|
|
287
|
-
) ->
|
|
325
|
+
) -> str | None:
|
|
288
326
|
"""
|
|
289
327
|
Returns a web app URL to open the websocket as a data source.
|
|
290
328
|
|
|
@@ -299,7 +337,7 @@ class WebSocketServer:
|
|
|
299
337
|
"""Explicitly stop the server."""
|
|
300
338
|
...
|
|
301
339
|
|
|
302
|
-
def clear_session(self, session_id:
|
|
340
|
+
def clear_session(self, session_id: str | None = None) -> None:
|
|
303
341
|
"""
|
|
304
342
|
Sets a new session ID and notifies all clients, causing them to reset their state.
|
|
305
343
|
If no session ID is provided, generates a new one based on the current timestamp.
|
|
@@ -307,6 +345,12 @@ class WebSocketServer:
|
|
|
307
345
|
"""
|
|
308
346
|
...
|
|
309
347
|
|
|
348
|
+
def broadcast_playback_state(self, playback_state: PlaybackState) -> None:
|
|
349
|
+
"""
|
|
350
|
+
Publish the current playback state to all clients.
|
|
351
|
+
"""
|
|
352
|
+
...
|
|
353
|
+
|
|
310
354
|
def broadcast_time(self, timestamp_nanos: int) -> None:
|
|
311
355
|
"""
|
|
312
356
|
Publishes the current server timestamp to all clients.
|
|
@@ -314,12 +358,12 @@ class WebSocketServer:
|
|
|
314
358
|
"""
|
|
315
359
|
...
|
|
316
360
|
|
|
317
|
-
def publish_parameter_values(self, parameters:
|
|
361
|
+
def publish_parameter_values(self, parameters: list[Parameter]) -> None:
|
|
318
362
|
"""Publishes parameter values to all subscribed clients."""
|
|
319
363
|
...
|
|
320
364
|
|
|
321
365
|
def publish_status(
|
|
322
|
-
self, message: str, level:
|
|
366
|
+
self, message: str, level: StatusLevel, id: str | None = None
|
|
323
367
|
) -> None:
|
|
324
368
|
"""
|
|
325
369
|
Send a status message to all clients. If the server has been stopped, this has no effect.
|
|
@@ -333,7 +377,7 @@ class WebSocketServer:
|
|
|
333
377
|
"""
|
|
334
378
|
...
|
|
335
379
|
|
|
336
|
-
def add_services(self, services: list[
|
|
380
|
+
def add_services(self, services: list[Service]) -> None:
|
|
337
381
|
"""Add services to the server."""
|
|
338
382
|
...
|
|
339
383
|
|
|
@@ -341,7 +385,7 @@ class WebSocketServer:
|
|
|
341
385
|
"""Removes services that were previously advertised."""
|
|
342
386
|
...
|
|
343
387
|
|
|
344
|
-
def publish_connection_graph(self, graph:
|
|
388
|
+
def publish_connection_graph(self, graph: ConnectionGraph) -> None:
|
|
345
389
|
"""
|
|
346
390
|
Publishes a connection graph update to all subscribed clients. An update is published to
|
|
347
391
|
clients as a difference from the current graph to the replacement graph. When a client first
|
|
Binary file
|
foxglove/channel.py
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import hashlib
|
|
2
4
|
import json
|
|
3
5
|
from base64 import b64encode
|
|
4
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, cast
|
|
5
7
|
|
|
6
8
|
from . import Context
|
|
7
9
|
from . import _foxglove_py as _foxglove
|
|
8
10
|
from . import channels as _channels
|
|
9
11
|
from . import schemas as _schemas
|
|
10
12
|
|
|
11
|
-
JsonSchema =
|
|
12
|
-
JsonMessage =
|
|
13
|
+
JsonSchema = dict[str, Any]
|
|
14
|
+
JsonMessage = dict[str, Any]
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class Channel:
|
|
@@ -24,16 +26,16 @@ class Channel:
|
|
|
24
26
|
self,
|
|
25
27
|
topic: str,
|
|
26
28
|
*,
|
|
27
|
-
schema:
|
|
28
|
-
message_encoding:
|
|
29
|
-
context:
|
|
30
|
-
metadata:
|
|
31
|
-
):
|
|
29
|
+
schema: JsonSchema | _foxglove.Schema | None = None,
|
|
30
|
+
message_encoding: str | None = None,
|
|
31
|
+
context: Context | None = None,
|
|
32
|
+
metadata: dict[str, str] | None = None,
|
|
33
|
+
) -> None:
|
|
32
34
|
"""
|
|
33
35
|
Create a new channel for logging messages on a topic.
|
|
34
36
|
|
|
35
37
|
:param topic: The topic name. You should choose a unique topic name per channel.
|
|
36
|
-
:param message_encoding: The message encoding. Optional if :
|
|
38
|
+
:param message_encoding: The message encoding. Optional if :any:`schema` is a
|
|
37
39
|
dictionary, in which case the message encoding is presumed to be "json".
|
|
38
40
|
:param schema: A definition of your schema. Pass a :py:class:`Schema` for full control. If a
|
|
39
41
|
dictionary is passed, it will be treated as a JSON schema.
|
|
@@ -75,7 +77,7 @@ class Channel:
|
|
|
75
77
|
"""The message encoding for the channel"""
|
|
76
78
|
return self.base.message_encoding
|
|
77
79
|
|
|
78
|
-
def metadata(self) ->
|
|
80
|
+
def metadata(self) -> dict[str, str]:
|
|
79
81
|
"""
|
|
80
82
|
Returns a copy of the channel's metadata.
|
|
81
83
|
|
|
@@ -84,7 +86,7 @@ class Channel:
|
|
|
84
86
|
"""
|
|
85
87
|
return self.base.metadata()
|
|
86
88
|
|
|
87
|
-
def schema(self) ->
|
|
89
|
+
def schema(self) -> _foxglove.Schema | None:
|
|
88
90
|
"""
|
|
89
91
|
Returns a copy of the channel's metadata.
|
|
90
92
|
|
|
@@ -93,7 +95,7 @@ class Channel:
|
|
|
93
95
|
"""
|
|
94
96
|
return self.base.schema()
|
|
95
97
|
|
|
96
|
-
def schema_name(self) ->
|
|
98
|
+
def schema_name(self) -> str | None:
|
|
97
99
|
"""The name of the schema for the channel"""
|
|
98
100
|
return self.base.schema_name()
|
|
99
101
|
|
|
@@ -103,10 +105,10 @@ class Channel:
|
|
|
103
105
|
|
|
104
106
|
def log(
|
|
105
107
|
self,
|
|
106
|
-
msg:
|
|
108
|
+
msg: JsonMessage | list[Any] | bytes | str,
|
|
107
109
|
*,
|
|
108
|
-
log_time:
|
|
109
|
-
sink_id:
|
|
110
|
+
log_time: int | None = None,
|
|
111
|
+
sink_id: int | None = None,
|
|
110
112
|
) -> None:
|
|
111
113
|
"""
|
|
112
114
|
Log a message on the channel.
|
|
@@ -138,15 +140,15 @@ class Channel:
|
|
|
138
140
|
self.base.close()
|
|
139
141
|
|
|
140
142
|
|
|
141
|
-
_channels_by_id:
|
|
143
|
+
_channels_by_id: dict[int, Channel] = {}
|
|
142
144
|
|
|
143
145
|
|
|
144
146
|
def log(
|
|
145
147
|
topic: str,
|
|
146
|
-
message:
|
|
148
|
+
message: JsonMessage | list[Any] | bytes | str | _schemas.FoxgloveSchema,
|
|
147
149
|
*,
|
|
148
|
-
log_time:
|
|
149
|
-
sink_id:
|
|
150
|
+
log_time: int | None = None,
|
|
151
|
+
sink_id: int | None = None,
|
|
150
152
|
) -> None:
|
|
151
153
|
"""Log a message on a topic.
|
|
152
154
|
|
|
@@ -197,9 +199,9 @@ def log(
|
|
|
197
199
|
|
|
198
200
|
|
|
199
201
|
def _normalize_schema(
|
|
200
|
-
message_encoding:
|
|
201
|
-
schema:
|
|
202
|
-
) -> tuple[str,
|
|
202
|
+
message_encoding: str | None,
|
|
203
|
+
schema: JsonSchema | _foxglove.Schema | None = None,
|
|
204
|
+
) -> tuple[str, _foxglove.Schema | None]:
|
|
203
205
|
if isinstance(schema, _foxglove.Schema):
|
|
204
206
|
if message_encoding is None:
|
|
205
207
|
raise ValueError("message encoding is required")
|
foxglove/channels/__init__.py
CHANGED
|
@@ -29,6 +29,7 @@ from foxglove._foxglove_py.channels import (
|
|
|
29
29
|
PackedElementFieldChannel,
|
|
30
30
|
Point2Channel,
|
|
31
31
|
Point3Channel,
|
|
32
|
+
Point3InFrameChannel,
|
|
32
33
|
PointCloudChannel,
|
|
33
34
|
PointsAnnotationChannel,
|
|
34
35
|
PoseChannel,
|
|
@@ -73,6 +74,7 @@ __all__ = [
|
|
|
73
74
|
"PackedElementFieldChannel",
|
|
74
75
|
"Point2Channel",
|
|
75
76
|
"Point3Channel",
|
|
77
|
+
"Point3InFrameChannel",
|
|
76
78
|
"PointCloudChannel",
|
|
77
79
|
"PointsAnnotationChannel",
|
|
78
80
|
"PoseChannel",
|
foxglove/cloud.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
|
|
3
|
+
from ._foxglove_py.websocket import (
|
|
4
|
+
ChannelView,
|
|
5
|
+
Client,
|
|
6
|
+
ClientChannel,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CloudSinkListener(Protocol):
|
|
11
|
+
"""
|
|
12
|
+
A mechanism to register callbacks for handling client message events.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def on_subscribe(self, client: Client, channel: ChannelView) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Called when a client subscribes to a channel.
|
|
18
|
+
|
|
19
|
+
:param client: The client (id) that sent the message.
|
|
20
|
+
:param channel: The channel (id, topic) that the message was sent on.
|
|
21
|
+
"""
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
def on_unsubscribe(self, client: Client, channel: ChannelView) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Called when a client unsubscribes from a channel or disconnects.
|
|
27
|
+
|
|
28
|
+
:param client: The client (id) that sent the message.
|
|
29
|
+
:param channel: The channel (id, topic) that the message was sent on.
|
|
30
|
+
"""
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
def on_client_advertise(self, client: Client, channel: ClientChannel) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Called when a client advertises a channel.
|
|
36
|
+
|
|
37
|
+
:param client: The client (id) that sent the message.
|
|
38
|
+
:param channel: The client channel that is being advertised.
|
|
39
|
+
"""
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
def on_client_unadvertise(self, client: Client, client_channel_id: int) -> None:
|
|
43
|
+
"""
|
|
44
|
+
Called when a client unadvertises a channel.
|
|
45
|
+
|
|
46
|
+
:param client: The client (id) that is unadvertising the channel.
|
|
47
|
+
:param client_channel_id: The client channel id that is being unadvertised.
|
|
48
|
+
"""
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
def on_message_data(
|
|
52
|
+
self, client: Client, client_channel_id: int, data: bytes
|
|
53
|
+
) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Called when a message is received from a client.
|
|
56
|
+
|
|
57
|
+
:param client: The client (id) that sent the message.
|
|
58
|
+
:param client_channel_id: The client channel id that the message was sent on.
|
|
59
|
+
:param data: The message data.
|
|
60
|
+
"""
|
|
61
|
+
return None
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines types for programmatically constructing Foxglove `layouts <https://docs.foxglove.dev/docs/visualization/layouts>`_.
|
|
3
|
+
|
|
4
|
+
This API is currently experimental and not ready for public use.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Layout:
|
|
9
|
+
"""A Foxglove layout
|
|
10
|
+
|
|
11
|
+
:raises NotImplementedError: This class is currently experimental and not ready for public use.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def to_json(self) -> str:
|
|
15
|
+
raise NotImplementedError(
|
|
16
|
+
"This class is currently experimental and not ready for public use."
|
|
17
|
+
)
|
|
File without changes
|