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.
@@ -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 __new__(
10
- cls,
8
+ def __init__(
9
+ self,
11
10
  sec: int,
12
- nsec: Optional[int] = None,
13
- ) -> "Duration": ...
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 __new__(
46
- cls,
44
+ def __init__(
45
+ self,
47
46
  sec: int,
48
- nsec: Optional[int] = None,
49
- ) -> "Timestamp": ...
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 foxglove
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
- Connectiongraph = ...
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: Optional[str] = ...
52
- schema: Optional[bytes] = ...
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 __new__(cls) -> "ConnectionGraph": ...
60
- def set_published_topic(self, topic: str, publisher_ids: List[str]) -> None:
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: List[str]) -> None:
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: List[str]) -> None:
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: "foxglove.Schema"
102
+ schema: Schema
97
103
 
98
- def __new__(
99
- cls,
104
+ def __init__(
105
+ self,
100
106
  *,
101
107
  encoding: str,
102
- schema: "foxglove.Schema",
103
- ) -> "MessageSchema": ...
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: Optional["ParameterType"]
120
- value: Optional["AnyParameterValue"]
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: Optional["AnyNativeParameterValue"] = None,
127
- type: Optional["ParameterType"] = None,
132
+ value: AnyNativeParameterValue | None = None,
133
+ type: ParameterType | None = None,
128
134
  ) -> None: ...
129
- def get_value(self) -> Optional["AnyNativeParameterValue"]:
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 __new__(cls, value: int) -> "ParameterValue.Integer": ...
161
+ def __init__(self, value: int) -> None: ...
156
162
 
157
163
  class Bool:
158
164
  """A boolean value."""
159
165
 
160
- def __new__(cls, value: bool) -> "ParameterValue.Bool": ...
166
+ def __init__(self, value: bool) -> None: ...
161
167
 
162
168
  class Float64:
163
169
  """A floating-point value."""
164
170
 
165
- def __new__(cls, value: float) -> "ParameterValue.Float64": ...
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 __new__(cls, value: str) -> "ParameterValue.String": ...
181
+ def __init__(self, value: str) -> None: ...
176
182
 
177
183
  class Array:
178
184
  """An array of parameter values."""
179
185
 
180
- def __new__(
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 __new__(
188
- cls, value: dict[str, "AnyParameterValue"]
189
- ) -> "ParameterValue.Dict": ...
191
+ def __init__(self, value: dict[str, AnyParameterValue]) -> None: ...
190
192
 
191
- AnyParameterValue = Union[
192
- ParameterValue.Integer,
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
- AnyInnerParameterValue = Union[
201
- AnyParameterValue,
202
- bool,
203
- int,
204
- float,
205
- str,
206
- List["AnyInnerParameterValue"],
207
- Dict[str, "AnyInnerParameterValue"],
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
- AnyNativeParameterValue = Union[
211
- AnyInnerParameterValue,
212
- bytes,
213
- ]
234
+ status: PlaybackStatus
235
+ current_time: int
236
+ playback_speed: float
237
+ did_seek: bool
238
+ request_id: str | None
214
239
 
215
- AssetHandler = Callable[[str], Optional[bytes]]
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: "ServiceSchema"
237
- handler: "ServiceHandler"
274
+ schema: ServiceSchema
275
+ handler: ServiceHandler
238
276
 
239
- def __new__(
240
- cls,
277
+ def __init__(
278
+ self,
241
279
  *,
242
280
  name: str,
243
- schema: "ServiceSchema",
244
- handler: "ServiceHandler",
245
- ) -> "Service": ...
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: Optional["MessageSchema"]
254
- response: Optional["MessageSchema"]
291
+ request: MessageSchema | None
292
+ response: MessageSchema | None
255
293
 
256
- def __new__(
257
- cls,
294
+ def __init__(
295
+ self,
258
296
  *,
259
297
  name: str,
260
- request: Optional["MessageSchema"] = None,
261
- response: Optional["MessageSchema"] = None,
262
- ) -> "ServiceSchema": ...
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 __new__(cls) -> "WebSocketServer": ...
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: Optional[str] = None,
323
+ layout_id: str | None = None,
286
324
  open_in_desktop: bool = False,
287
- ) -> Optional[str]:
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: Optional[str] = None) -> None:
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: List["Parameter"]) -> None:
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: "StatusLevel", id: Optional[str] = None
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["Service"]) -> None:
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: "ConnectionGraph") -> None:
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
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, Dict, Optional, Union, cast
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 = Dict[str, Any]
12
- JsonMessage = Dict[str, Any]
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: Union[JsonSchema, _foxglove.Schema, None] = None,
28
- message_encoding: Optional[str] = None,
29
- context: Optional[Context] = None,
30
- metadata: Optional[Dict[str, str]] = None,
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 :py:param:`schema` is a
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) -> Dict[str, str]:
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) -> Optional[_foxglove.Schema]:
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) -> Optional[str]:
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: Union[JsonMessage, list[Any], bytes, str],
108
+ msg: JsonMessage | list[Any] | bytes | str,
107
109
  *,
108
- log_time: Optional[int] = None,
109
- sink_id: Optional[int] = None,
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: Dict[int, Channel] = {}
143
+ _channels_by_id: dict[int, Channel] = {}
142
144
 
143
145
 
144
146
  def log(
145
147
  topic: str,
146
- message: Union[JsonMessage, list[Any], bytes, str, _schemas.FoxgloveSchema],
148
+ message: JsonMessage | list[Any] | bytes | str | _schemas.FoxgloveSchema,
147
149
  *,
148
- log_time: Optional[int] = None,
149
- sink_id: Optional[int] = None,
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: Optional[str],
201
- schema: Union[JsonSchema, _foxglove.Schema, None] = None,
202
- ) -> tuple[str, Optional[_foxglove.Schema]]:
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")
@@ -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