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 CHANGED
@@ -1,124 +1,245 @@
1
- """
2
- This module provides interfaces for logging messages to Foxglove.
3
-
4
- See :py:mod:`foxglove.schemas` and :py:mod:`foxglove.channels` for working with well-known Foxglove
5
- schemas.
6
- """
7
-
8
- import atexit
9
- import logging
10
- from typing import List, Optional, Union
11
-
12
- from . import _foxglove_py as _foxglove
13
-
14
- # Re-export these imports
15
- from ._foxglove_py import Context, Schema, open_mcap
16
- from .channel import Channel, log
17
-
18
- # Deprecated. Use foxglove.mcap.MCAPWriter instead.
19
- from .mcap import MCAPWriter
20
- from .websocket import (
21
- AssetHandler,
22
- Capability,
23
- ServerListener,
24
- Service,
25
- WebSocketServer,
26
- )
27
-
28
- atexit.register(_foxglove.shutdown)
29
-
30
-
31
- def start_server(
32
- *,
33
- name: Optional[str] = None,
34
- host: Optional[str] = "127.0.0.1",
35
- port: Optional[int] = 8765,
36
- capabilities: Optional[List[Capability]] = None,
37
- server_listener: Optional[ServerListener] = None,
38
- supported_encodings: Optional[List[str]] = None,
39
- services: Optional[List[Service]] = None,
40
- asset_handler: Optional[AssetHandler] = None,
41
- context: Optional[Context] = None,
42
- ) -> WebSocketServer:
43
- """
44
- Start a websocket server for live visualization.
45
-
46
- :param name: The name of the server.
47
- :param host: The host to bind to.
48
- :param port: The port to bind to.
49
- :param capabilities: A list of capabilities to advertise to clients.
50
- :param server_listener: A Python object that implements the :py:class:`websocket.ServerListener`
51
- protocol.
52
- :param supported_encodings: A list of encodings to advertise to clients.
53
- :param services: A list of services to advertise to clients.
54
- :param asset_handler: A callback function that returns the asset for a given URI, or None if
55
- it doesn't exist.
56
- :param context: The context to use for logging. If None, the global context is used.
57
- """
58
- return _foxglove.start_server(
59
- name=name,
60
- host=host,
61
- port=port,
62
- capabilities=capabilities,
63
- server_listener=server_listener,
64
- supported_encodings=supported_encodings,
65
- services=services,
66
- asset_handler=asset_handler,
67
- context=context,
68
- )
69
-
70
-
71
- def set_log_level(level: Union[int, str] = "INFO") -> None:
72
- """
73
- Enable SDK logging.
74
-
75
- This function will call logging.basicConfig() for convenience in scripts, but in general you
76
- should configure logging yourself before calling this function:
77
- https://docs.python.org/3/library/logging.html
78
-
79
- :param level: The logging level to set. This accepts the same values as `logging.setLevel` and
80
- defaults to "INFO". The SDK will not log at levels "CRITICAL" or higher.
81
- """
82
- # This will raise a ValueError for invalid levels if the user has not already configured
83
- logging.basicConfig(level=level, format="%(asctime)s [%(levelname)s] %(message)s")
84
-
85
- if isinstance(level, str):
86
- level_map = (
87
- logging.getLevelNamesMapping()
88
- if hasattr(logging, "getLevelNamesMapping")
89
- else _level_names()
90
- )
91
- try:
92
- level = level_map[level]
93
- except KeyError:
94
- raise ValueError(f"Unknown log level: {level}")
95
- else:
96
- level = max(0, min(2**32 - 1, level))
97
-
98
- _foxglove.enable_logging(level)
99
-
100
-
101
- def _level_names() -> dict[str, int]:
102
- # Fallback for Python <3.11; no support for custom levels
103
- return {
104
- "CRITICAL": logging.CRITICAL,
105
- "FATAL": logging.FATAL,
106
- "ERROR": logging.ERROR,
107
- "WARN": logging.WARNING,
108
- "WARNING": logging.WARNING,
109
- "INFO": logging.INFO,
110
- "DEBUG": logging.DEBUG,
111
- "NOTSET": logging.NOTSET,
112
- }
113
-
114
-
115
- __all__ = [
116
- "Channel",
117
- "Context",
118
- "MCAPWriter",
119
- "Schema",
120
- "log",
121
- "open_mcap",
122
- "set_log_level",
123
- "start_server",
124
- ]
1
+ """
2
+ This module provides interfaces for logging messages to Foxglove.
3
+
4
+ See :py:mod:`foxglove.schemas` and :py:mod:`foxglove.channels` for working with well-known Foxglove
5
+ schemas.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import atexit
11
+ import logging
12
+ from typing import TYPE_CHECKING
13
+
14
+ from . import _foxglove_py as _foxglove
15
+
16
+ # Re-export these imports
17
+ from ._foxglove_py import (
18
+ ChannelDescriptor,
19
+ Context,
20
+ Schema,
21
+ SinkChannelFilter,
22
+ open_mcap,
23
+ )
24
+ from .channel import Channel, log
25
+
26
+ # Deprecated. Use foxglove.mcap.MCAPWriter instead.
27
+ from .mcap import MCAPWriter
28
+
29
+ if TYPE_CHECKING:
30
+ from .notebook.notebook_buffer import NotebookBuffer
31
+
32
+ atexit.register(_foxglove.shutdown)
33
+
34
+
35
+ try:
36
+ from ._foxglove_py.cloud import CloudSink
37
+
38
+ # from ._foxglove_py.cloud import start_cloud_sink as _start_cloud_sink
39
+ from .cloud import CloudSinkListener
40
+ from .websocket import (
41
+ AssetHandler,
42
+ Capability,
43
+ ServerListener,
44
+ Service,
45
+ WebSocketServer,
46
+ )
47
+
48
+ def start_server(
49
+ *,
50
+ name: str | None = None,
51
+ host: str | None = "127.0.0.1",
52
+ port: int | None = 8765,
53
+ capabilities: list[Capability] | None = None,
54
+ server_listener: ServerListener | None = None,
55
+ supported_encodings: list[str] | None = None,
56
+ services: list[Service] | None = None,
57
+ asset_handler: AssetHandler | None = None,
58
+ context: Context | None = None,
59
+ session_id: str | None = None,
60
+ channel_filter: SinkChannelFilter | None = None,
61
+ playback_time_range: tuple[int, int] | None = None,
62
+ ) -> WebSocketServer:
63
+ """
64
+ Start a websocket server for live visualization.
65
+
66
+ :param name: The name of the server.
67
+ :param host: The host to bind to.
68
+ :param port: The port to bind to.
69
+ :param capabilities: A list of capabilities to advertise to clients.
70
+ :param server_listener: A Python object that implements the
71
+ :py:class:`websocket.ServerListener` protocol.
72
+ :param supported_encodings: A list of encodings to advertise to clients.
73
+ :param services: A list of services to advertise to clients.
74
+ :param asset_handler: A callback function that returns the asset for a given URI, or None if
75
+ it doesn't exist.
76
+ :param context: The context to use for logging. If None, the global context is used.
77
+ :param session_id: An ID which allows the client to understand if the connection is a
78
+ re-connection or a new server instance. If None, then an ID is generated based on the
79
+ current time.
80
+ :param channel_filter: A `Callable` that determines whether a channel should be logged to.
81
+ Return `True` to log the channel, or `False` to skip it. By default, all channels
82
+ will be logged.
83
+ :param playback_time_range: Time range of data being played back, in absolute nanoseconds.
84
+ Implies `Capability.RangedPlayback` if set.
85
+ """
86
+ return _foxglove.start_server(
87
+ name=name,
88
+ host=host,
89
+ port=port,
90
+ capabilities=capabilities,
91
+ server_listener=server_listener,
92
+ supported_encodings=supported_encodings,
93
+ services=services,
94
+ asset_handler=asset_handler,
95
+ context=context,
96
+ session_id=session_id,
97
+ channel_filter=channel_filter,
98
+ playback_time_range=playback_time_range,
99
+ )
100
+
101
+ def start_cloud_sink(
102
+ *,
103
+ listener: CloudSinkListener | None = None,
104
+ supported_encodings: list[str] | None = None,
105
+ context: Context | None = None,
106
+ session_id: str | None = None,
107
+ ) -> CloudSink:
108
+ """
109
+ Connect to Foxglove Agent for live visualization and teleop.
110
+
111
+ Foxglove Agent must be running on the same host for this to work.
112
+
113
+ :param capabilities: A list of capabilities to advertise to the agent.
114
+ :param listener: A Python object that implements the
115
+ :py:class:`cloud.CloudSinkListener` protocol.
116
+ :param supported_encodings: A list of encodings to advertise to the agent.
117
+ :param context: The context to use for logging. If None, the global context is used.
118
+ :param session_id: An ID which allows the agent to understand if the connection is a
119
+ re-connection or a new connection instance. If None, then an ID is generated based on
120
+ the current time.
121
+ """
122
+ return _foxglove.start_cloud_sink(
123
+ listener=listener,
124
+ supported_encodings=supported_encodings,
125
+ context=context,
126
+ session_id=session_id,
127
+ )
128
+
129
+ except ImportError:
130
+ pass
131
+
132
+
133
+ def set_log_level(level: int | str = "INFO") -> None:
134
+ """
135
+ Enable SDK logging.
136
+
137
+ This function will call logging.basicConfig() for convenience in scripts, but in general you
138
+ should configure logging yourself before calling this function:
139
+ https://docs.python.org/3/library/logging.html
140
+
141
+ :param level: The logging level to set. This accepts the same values as `logging.setLevel` and
142
+ defaults to "INFO". The SDK will not log at levels "CRITICAL" or higher.
143
+ """
144
+ # This will raise a ValueError for invalid levels if the user has not already configured
145
+ logging.basicConfig(level=level, format="%(asctime)s [%(levelname)s] %(message)s")
146
+
147
+ if isinstance(level, str):
148
+ level_map = (
149
+ logging.getLevelNamesMapping()
150
+ if hasattr(logging, "getLevelNamesMapping")
151
+ else _level_names()
152
+ )
153
+ try:
154
+ level = level_map[level]
155
+ except KeyError:
156
+ raise ValueError(f"Unknown log level: {level}")
157
+ else:
158
+ level = max(0, min(2**32 - 1, level))
159
+
160
+ _foxglove.enable_logging(level)
161
+
162
+
163
+ def _level_names() -> dict[str, int]:
164
+ # Fallback for Python <3.11; no support for custom levels
165
+ return {
166
+ "CRITICAL": logging.CRITICAL,
167
+ "FATAL": logging.FATAL,
168
+ "ERROR": logging.ERROR,
169
+ "WARN": logging.WARNING,
170
+ "WARNING": logging.WARNING,
171
+ "INFO": logging.INFO,
172
+ "DEBUG": logging.DEBUG,
173
+ "NOTSET": logging.NOTSET,
174
+ }
175
+
176
+
177
+ def init_notebook_buffer(context: Context | None = None) -> NotebookBuffer:
178
+ """
179
+ Create a NotebookBuffer object to manage data buffering and visualization in Jupyter
180
+ notebooks.
181
+
182
+ The NotebookBuffer object will buffer all data logged to the provided context. When you
183
+ are ready to visualize the data, you can call the :meth:`show` method to display an embedded
184
+ Foxglove visualization widget. The widget provides a fully-featured Foxglove interface
185
+ directly within your Jupyter notebook, allowing you to explore multi-modal robotics data
186
+ including 3D scenes, plots, images, and more.
187
+
188
+ Args:
189
+ context: The Context used to log the messages. If no Context is provided, the global
190
+ context will be used. Logged messages will be buffered.
191
+
192
+ Returns:
193
+ NotebookBuffer: A NotebookBuffer object that can be used to manage the data buffering
194
+ and visualization.
195
+
196
+ Raises:
197
+ Exception: If the notebook extra package is not installed. Install it
198
+ with `pip install foxglove-sdk[notebook]`.
199
+
200
+ Note:
201
+ This function is only available when the `notebook` extra package
202
+ is installed. Install it with `pip install foxglove-sdk[notebook]`.
203
+
204
+ Example:
205
+ >>> import foxglove
206
+ >>>
207
+ >>> # Create a basic viewer using the default context
208
+ >>> nb_buffer = foxglove.init_notebook_buffer()
209
+ >>>
210
+ >>> # Or use a specific context
211
+ >>> nb_buffer = foxglove.init_notebook_buffer(context=my_ctx)
212
+ >>>
213
+ >>> # ... log data as usual ...
214
+ >>>
215
+ >>> # Display the widget in the notebook
216
+ >>> nb_buffer.show()
217
+ """
218
+ try:
219
+ from .notebook.notebook_buffer import NotebookBuffer
220
+
221
+ except ImportError:
222
+ raise Exception(
223
+ "NotebookBuffer is not installed. "
224
+ 'Please install it with `pip install "foxglove-sdk[notebook]"`'
225
+ )
226
+
227
+ return NotebookBuffer(context=context)
228
+
229
+
230
+ __all__ = [
231
+ "Channel",
232
+ "ChannelDescriptor",
233
+ "Context",
234
+ "MCAPWriter",
235
+ "Schema",
236
+ "SinkChannelFilter",
237
+ "CloudSink",
238
+ "CloudSinkListener",
239
+ "start_cloud_sink",
240
+ "log",
241
+ "open_mcap",
242
+ "set_log_level",
243
+ "start_server",
244
+ "init_notebook_buffer",
245
+ ]