A Python client for foxglove_bridge with a
roslibpy-compatible API surface.
It speaks the Foxglove WebSocket protocol instead of the rosbridge JSON
protocol.
The canonical import package is foxglove_ros_client:
from foxglove_ros_client import Ros, Topic, Message, Service, ServiceRequest, ParamThis is an early runtime-focused implementation for ROS 2 systems exposed by
foxglove_bridge.
Supported:
Ros(host, port=None, is_secure=False, headers=None, ca_cert_file=None)withrun(),run_forever(),close(),terminate(),on(),off(),on_ready(),call_later(), andis_connected.Topic(...).subscribe(),unsubscribe(),publish(),advertise(),unadvertise().Service(...).call()with blocking and callback forms.Param(...).get()andset()through Foxglove parameter operations.- Rosapi-style discovery helpers backed by Foxglove advertisements:
get_topics(),get_topic_type(),get_topics_for_type(),get_services(),get_service_type(),get_services_for_type(),get_message_details(),get_service_request_details(),get_service_response_details(),get_nodes(),get_node_details(), and action-server discovery. - ROS 2
ActionClient.send_goal(),cancel_goal(), andwait_goal()when the bridge advertises hidden action endpoints. UseRos.wait_for_action()to wait until a specific action is ready before sending a goal. - Full parameter listing via
get_params()and best-effort parameter deletion viadelete_param()/Param.delete()when the server accepts parameter updates. - ROS 1-style
foxglove_ros_client.ros1.actionlib.ActionClient,Goal, andSimpleActionServerover action topics. TFClientover/tfand/tf_static, including fixed-frame resolution across parent/child transform chains.- Dict-like
Message,ServiceRequest,ServiceResponse,Goal,Result,Feedback,Time,Header, andfoxglove_ros_client.ros2.Header. - A
foxglove-ros-client-pycommand-line entry point with roslibpy-styletopic,msg,service,srv, andparamsubcommands.
Not supported:
- Client-side service advertisement.
foxglove_bridgedoes not expose a WebSocket protocol for Python clients to serve ROS services.
Notes:
get_nodes()andget_node_details()use Foxglove connection graph updates. They return data only when the server advertises theconnectionGraphcapability.get_params()requests all currently set parameters withgetParameters. Parameter deletion is represented as asetParametersrequest with an unset value; a ROS bridge or node can still reject the change for normal middleware reasons such as read-only or undeclared parameters.
git clone https://github.com/PickNikRobotics/foxglove-ros-client-py.git
python -m pip install ./foxglove-ros-client-pyStart the ROS 2 Foxglove bridge:
ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765For ROS 2 actions, start the bridge with hidden topics and services included:
ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765 include_hidden:=trueFoxglove exposes ROS 2 actions through the hidden /_action/* services and
topics. This differs from rosbridge/actionlib topic wiring; ActionClient uses
Foxglove service calls to send_goal, get_result, and cancel_goal.
Use the familiar API shape:
from foxglove_ros_client import Message, Ros, Topic
ros = Ros("localhost", 8765)
ros.run()
listener = Topic(ros, "/chatter", "std_msgs/msg/String")
listener.subscribe(lambda msg: print(msg["data"]))
talker = Topic(ros, "/python/chatter", "std_msgs/msg/String")
talker.publish(Message({"data": "hello from Python"}))Wrap run() and subsequent work in try / finally and call close() from
the finally block. close() also cancels a connection attempt that times out
before the WebSocket opens.
Pass WebSocket handshake headers to Ros when the endpoint requires authentication:
import os
from foxglove_ros_client import Ros
ros = Ros(
"robot.example",
3201,
is_secure=True,
headers={"Authorization": f"Bearer {os.environ['MOVEIT_FRONTEND_KEY']}"},
ca_cert_file="/path/to/runtime-cert-or-ca.pem",
)
ros.run()ca_cert_file is optional when the endpoint certificate is already trusted by the client runtime.
Keep certificate verification enabled.
std_msgs/String and std_msgs/msg/String are both accepted. Subscription and
service responses are decoded from CDR using schemas advertised by the bridge.
Publishing uses CDR when a matching schema has been advertised, otherwise it
falls back to Foxglove's JSON client-channel encoding.
python -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[test]"
pytest
python -m buildThe command-line helper can be run after installation:
foxglove-ros-client-py -r localhost -p 8765 topic listThe live smoke test exercises topic subscription, publishing, parameter reads, service discovery, and action discovery without sending action goals:
python examples/live_bridge_check.py --url ws://localhost:8765Service calls are optional and generic:
python examples/live_bridge_check.py \
--url ws://localhost:8765 \
--service-name /example_service \
--service-type example_interfaces/srv/Trigger \
--service-request-json '{}'Action execution is intentionally double-gated:
python examples/live_bridge_check.py \
--url ws://localhost:8765 \
--action-mode send-goal \
--action-name /example_action \
--action-type example_interfaces/action/Fibonacci \
--action-goal-json '{"order": 5}' \
--allow-action-execution