foxglove-sdk 0.8.1__cp312-cp312-win32.whl → 0.16.3__cp312-cp312-win32.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.
Potentially problematic release.
This version of foxglove-sdk might be problematic. Click here for more details.
- foxglove/__init__.py +245 -124
- foxglove/_foxglove_py/__init__.pyi +233 -167
- foxglove/_foxglove_py/channels.pyi +2792 -2580
- foxglove/_foxglove_py/cloud.pyi +9 -0
- foxglove/_foxglove_py/mcap.pyi +125 -84
- foxglove/_foxglove_py/schemas.pyi +1009 -839
- foxglove/_foxglove_py/schemas_wkt.pyi +85 -77
- foxglove/_foxglove_py/websocket.pyi +394 -343
- foxglove/_foxglove_py.cp312-win32.pyd +0 -0
- foxglove/benchmarks/test_mcap_serialization.py +160 -160
- foxglove/channel.py +241 -234
- foxglove/channels/__init__.py +94 -90
- foxglove/cloud.py +61 -0
- foxglove/mcap.py +12 -12
- foxglove/notebook/__init__.py +0 -0
- foxglove/notebook/foxglove_widget.py +100 -0
- foxglove/notebook/notebook_buffer.py +114 -0
- foxglove/schemas/__init__.py +163 -155
- foxglove/tests/test_channel.py +243 -215
- foxglove/tests/test_context.py +10 -0
- foxglove/tests/test_logging.py +62 -16
- foxglove/tests/test_mcap.py +477 -116
- foxglove/tests/test_parameters.py +178 -154
- foxglove/tests/test_schemas.py +17 -0
- foxglove/tests/test_server.py +141 -110
- foxglove/tests/test_time.py +137 -137
- foxglove/websocket.py +220 -195
- foxglove_sdk-0.16.3.dist-info/METADATA +53 -0
- foxglove_sdk-0.16.3.dist-info/RECORD +32 -0
- {foxglove_sdk-0.8.1.dist-info → foxglove_sdk-0.16.3.dist-info}/WHEEL +1 -1
- foxglove_sdk-0.8.1.dist-info/METADATA +0 -51
- foxglove_sdk-0.8.1.dist-info/RECORD +0 -25
|
@@ -1,167 +1,233 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import Any,
|
|
3
|
-
|
|
4
|
-
from .
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
def
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
) -> None:
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"""
|
|
69
|
-
...
|
|
70
|
-
|
|
71
|
-
def
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"""
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
) ->
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
""
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
"""
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
""
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any, BinaryIO, Callable, Protocol
|
|
3
|
+
|
|
4
|
+
from foxglove.websocket import AssetHandler
|
|
5
|
+
|
|
6
|
+
class McapWritable(Protocol):
|
|
7
|
+
"""A writable and seekable file-like object.
|
|
8
|
+
|
|
9
|
+
This protocol defines the minimal interface required for writing MCAP data.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def write(self, data: bytes | bytearray) -> int:
|
|
13
|
+
"""Write data and return the number of bytes written."""
|
|
14
|
+
...
|
|
15
|
+
|
|
16
|
+
def seek(self, offset: int, whence: int = 0) -> int:
|
|
17
|
+
"""Seek to position and return the new absolute position."""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
def flush(self) -> None:
|
|
21
|
+
"""Flush any buffered data."""
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
from .cloud import CloudSink
|
|
25
|
+
from .mcap import MCAPWriteOptions, MCAPWriter
|
|
26
|
+
from .websocket import Capability, Service, WebSocketServer
|
|
27
|
+
|
|
28
|
+
class BaseChannel:
|
|
29
|
+
"""
|
|
30
|
+
A channel for logging messages.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
topic: str,
|
|
36
|
+
message_encoding: str,
|
|
37
|
+
schema: "Schema" | None = None,
|
|
38
|
+
metadata: dict[str, str] | None = None,
|
|
39
|
+
) -> None: ...
|
|
40
|
+
def id(self) -> int:
|
|
41
|
+
"""The unique ID of the channel"""
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
def topic(self) -> str:
|
|
45
|
+
"""The topic name of the channel"""
|
|
46
|
+
...
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def message_encoding(self) -> str:
|
|
50
|
+
"""The message encoding for the channel"""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
def metadata(self) -> dict[str, str]:
|
|
54
|
+
"""
|
|
55
|
+
Returns a copy of the channel's metadata.
|
|
56
|
+
|
|
57
|
+
Note that changes made to the returned dictionary will not be applied to
|
|
58
|
+
the channel's metadata.
|
|
59
|
+
"""
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
def schema(self) -> "Schema" | None:
|
|
63
|
+
"""
|
|
64
|
+
Returns a copy of the channel's schema.
|
|
65
|
+
|
|
66
|
+
Note that changes made to the returned object will not be applied to
|
|
67
|
+
the channel's schema.
|
|
68
|
+
"""
|
|
69
|
+
...
|
|
70
|
+
|
|
71
|
+
def schema_name(self) -> str | None:
|
|
72
|
+
"""The name of the schema for the channel"""
|
|
73
|
+
...
|
|
74
|
+
|
|
75
|
+
def has_sinks(self) -> bool:
|
|
76
|
+
"""Returns true if at least one sink is subscribed to this channel"""
|
|
77
|
+
...
|
|
78
|
+
|
|
79
|
+
def log(
|
|
80
|
+
self,
|
|
81
|
+
msg: bytes,
|
|
82
|
+
log_time: int | None = None,
|
|
83
|
+
sink_id: int | None = None,
|
|
84
|
+
) -> None:
|
|
85
|
+
"""
|
|
86
|
+
Log a message to the channel.
|
|
87
|
+
|
|
88
|
+
:param msg: The message to log.
|
|
89
|
+
:param log_time: The optional time the message was logged.
|
|
90
|
+
:param sink_id: The sink ID to log the message to. If not provided, the message will be
|
|
91
|
+
sent to all sinks.
|
|
92
|
+
"""
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
def close(self) -> None: ...
|
|
96
|
+
|
|
97
|
+
class Schema:
|
|
98
|
+
"""
|
|
99
|
+
A schema for a message or service call.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
name: str
|
|
103
|
+
encoding: str
|
|
104
|
+
data: bytes
|
|
105
|
+
|
|
106
|
+
def __init__(
|
|
107
|
+
self,
|
|
108
|
+
*,
|
|
109
|
+
name: str,
|
|
110
|
+
encoding: str,
|
|
111
|
+
data: bytes,
|
|
112
|
+
) -> None: ...
|
|
113
|
+
|
|
114
|
+
class Context:
|
|
115
|
+
"""
|
|
116
|
+
A context for logging messages.
|
|
117
|
+
|
|
118
|
+
A context is the binding between channels and sinks. By default, the SDK will use a single
|
|
119
|
+
global context for logging, but you can create multiple contexts in order to log to different
|
|
120
|
+
topics to different sinks or servers. To do so, associate the context by passing it to the
|
|
121
|
+
channel constructor and to :py:func:`open_mcap` or :py:func:`start_server`.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
def __init__(self) -> None: ...
|
|
125
|
+
def _create_channel(
|
|
126
|
+
self,
|
|
127
|
+
topic: str,
|
|
128
|
+
message_encoding: str,
|
|
129
|
+
schema: Schema | None = None,
|
|
130
|
+
metadata: list[tuple[str, str]] | None = None,
|
|
131
|
+
) -> "BaseChannel":
|
|
132
|
+
"""
|
|
133
|
+
Instead of calling this method, pass a context to a channel constructor.
|
|
134
|
+
"""
|
|
135
|
+
...
|
|
136
|
+
|
|
137
|
+
@staticmethod
|
|
138
|
+
def default() -> "Context":
|
|
139
|
+
"""
|
|
140
|
+
Returns the default context.
|
|
141
|
+
"""
|
|
142
|
+
...
|
|
143
|
+
|
|
144
|
+
class ChannelDescriptor:
|
|
145
|
+
"""
|
|
146
|
+
Information about a channel
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
id: int
|
|
150
|
+
topic: str
|
|
151
|
+
message_encoding: str
|
|
152
|
+
metadata: dict[str, str]
|
|
153
|
+
schema: "Schema" | None
|
|
154
|
+
|
|
155
|
+
SinkChannelFilter = Callable[[ChannelDescriptor], bool]
|
|
156
|
+
|
|
157
|
+
def start_server(
|
|
158
|
+
*,
|
|
159
|
+
name: str | None = None,
|
|
160
|
+
host: str | None = "127.0.0.1",
|
|
161
|
+
port: int | None = 8765,
|
|
162
|
+
capabilities: list[Capability] | None = None,
|
|
163
|
+
server_listener: Any = None,
|
|
164
|
+
supported_encodings: list[str] | None = None,
|
|
165
|
+
services: list[Service] | None = None,
|
|
166
|
+
asset_handler: AssetHandler | None = None,
|
|
167
|
+
context: Context | None = None,
|
|
168
|
+
session_id: str | None = None,
|
|
169
|
+
channel_filter: SinkChannelFilter | None = None,
|
|
170
|
+
playback_time_range: tuple[int, int] | None = None,
|
|
171
|
+
) -> WebSocketServer:
|
|
172
|
+
"""
|
|
173
|
+
Start a websocket server for live visualization.
|
|
174
|
+
"""
|
|
175
|
+
...
|
|
176
|
+
|
|
177
|
+
def start_cloud_sink(
|
|
178
|
+
*,
|
|
179
|
+
listener: Any = None,
|
|
180
|
+
supported_encodings: list[str] | None = None,
|
|
181
|
+
context: Context | None = None,
|
|
182
|
+
session_id: str | None = None,
|
|
183
|
+
) -> CloudSink:
|
|
184
|
+
"""
|
|
185
|
+
Connect to Foxglove Agent for remote visualization and teleop.
|
|
186
|
+
"""
|
|
187
|
+
...
|
|
188
|
+
|
|
189
|
+
def enable_logging(level: int) -> None:
|
|
190
|
+
"""
|
|
191
|
+
Forward SDK logs to python's logging facility.
|
|
192
|
+
"""
|
|
193
|
+
...
|
|
194
|
+
|
|
195
|
+
def disable_logging() -> None:
|
|
196
|
+
"""
|
|
197
|
+
Stop forwarding SDK logs.
|
|
198
|
+
"""
|
|
199
|
+
...
|
|
200
|
+
|
|
201
|
+
def shutdown() -> None:
|
|
202
|
+
"""
|
|
203
|
+
Shutdown the running websocket server.
|
|
204
|
+
"""
|
|
205
|
+
...
|
|
206
|
+
|
|
207
|
+
def open_mcap(
|
|
208
|
+
path: str | Path | BinaryIO | McapWritable,
|
|
209
|
+
*,
|
|
210
|
+
allow_overwrite: bool = False,
|
|
211
|
+
context: Context | None = None,
|
|
212
|
+
channel_filter: SinkChannelFilter | None = None,
|
|
213
|
+
writer_options: MCAPWriteOptions | None = None,
|
|
214
|
+
) -> MCAPWriter:
|
|
215
|
+
"""
|
|
216
|
+
Open an MCAP writer for recording.
|
|
217
|
+
|
|
218
|
+
If a path is provided, the file will be created and must not already exist (unless
|
|
219
|
+
allow_overwrite is True). If a file-like object is provided, it must support write(),
|
|
220
|
+
seek(), and flush() methods; the allow_overwrite parameter is ignored.
|
|
221
|
+
|
|
222
|
+
If a context is provided, the MCAP file will be associated with that context. Otherwise, the
|
|
223
|
+
global context will be used.
|
|
224
|
+
|
|
225
|
+
You must close the writer with close() or the with statement to ensure the file is correctly finished.
|
|
226
|
+
"""
|
|
227
|
+
...
|
|
228
|
+
|
|
229
|
+
def get_channel_for_topic(topic: str) -> BaseChannel | None:
|
|
230
|
+
"""
|
|
231
|
+
Get a previously-registered channel.
|
|
232
|
+
"""
|
|
233
|
+
...
|