Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions .github/workflows/test-ros1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:
"ubuntu-py39",
"ubuntu-py310",
"ubuntu-py311",
"ubuntu-py312",
"ubuntu-py313",
"ubuntu-py314",
]
include:
- name: "ubuntu-py39"
Expand All @@ -30,6 +33,15 @@ jobs:
- name: "ubuntu-py311"
os: ubuntu-latest
python-version: "3.11"
- name: "ubuntu-py312"
os: ubuntu-latest
python-version: "3.12"
- name: "ubuntu-py313"
os: ubuntu-latest
python-version: "3.13"
- name: "ubuntu-py314"
os: ubuntu-latest
python-version: "3.14"
steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -51,9 +63,16 @@ jobs:
- name: Run linter
run: |
invoke check
- name: Run tests
# The twisted and asyncio transports both build on Autobahn, whose txaio
# layer binds a single async framework per process, so each transport is
# exercised in its own pytest process.
- name: Run tests (twisted transport)
run: |
ROSLIBPY_TRANSPORT=twisted pytest tests/ros1
- name: Run tests (asyncio transport)
run: |
pytest tests/ros1
ROSLIBPY_TRANSPORT=asyncio pytest tests/ros1
- name: Tear down docker containers
if: always()
run: |
docker rm -f rosbridge
18 changes: 16 additions & 2 deletions .github/workflows/test-ros2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ jobs:
"ubuntu-py310",
"ubuntu-py311",
"ubuntu-py312",
"ubuntu-py313",
"ubuntu-py314",
]
include:
- name: "ubuntu-py39"
Expand All @@ -34,6 +36,12 @@ jobs:
- name: "ubuntu-py312"
os: ubuntu-latest
python-version: "3.12"
- name: "ubuntu-py313"
os: ubuntu-latest
python-version: "3.13"
- name: "ubuntu-py314"
os: ubuntu-latest
python-version: "3.14"
steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -55,9 +63,15 @@ jobs:
- name: Run linter
run: |
invoke check
- name: Run tests
# The twisted and asyncio transports both build on Autobahn, whose txaio
# layer binds a single async framework per process, so each transport is
# exercised in its own pytest process.
- name: Run tests (twisted transport)
run: |
ROSLIBPY_TRANSPORT=twisted pytest tests/ros2
- name: Run tests (asyncio transport)
run: |
pytest tests/ros2
ROSLIBPY_TRANSPORT=asyncio pytest tests/ros2
- name: Tear down docker containers
run: |
docker rm -f rosbridge
59 changes: 59 additions & 0 deletions .github/workflows/transport-benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Transport benchmark

on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
branches:
- main
workflow_dispatch:

jobs:
transport-benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python 3.11
uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install wheel
- name: Install
run: |
python -m pip install --no-cache-dir -r requirements-dev.txt
python -m pip install --no-cache-dir uvloop
- name: Set up docker containers
run: |
docker build -t gramaziokohler/rosbridge:integration_tests_ros1 ./docker/ros1
docker run -d -p 9090:9090 --name rosbridge gramaziokohler/rosbridge:integration_tests_ros1 /bin/bash -c "roslaunch /integration-tests.launch"
docker ps -a
- name: Run transport benchmark
continue-on-error: true
run: |
python benchmarks/transport.py \
--host 127.0.0.1 \
--port 9090 \
--cases twisted asyncio asyncio-uvloop asyncio-no-compression asyncio-uvloop-no-compression \
--warmup 100 \
--service-count 1500 \
--topic-count 3000 \
--markdown transport-benchmark.md
cat transport-benchmark.md >> "$GITHUB_STEP_SUMMARY"
- name: Upload transport benchmark
if: always()
continue-on-error: true
uses: actions/upload-artifact@v4
with:
name: transport-benchmark
path: transport-benchmark.md
if-no-files-found: ignore
- name: Tear down docker containers
if: always()
run: |
docker rm -f rosbridge
13 changes: 13 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2

build:
os: ubuntu-24.04
tools:
python: "3.14"

sphinx:
configuration: docs/conf.py

python:
install:
- requirements: docs/requirements.txt
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@ Unreleased

**Added**

* Added an asyncio transport backend (Autobahn running on an asyncio event
loop instead of the Twisted reactor) selectable with ``ROSLIBPY_TRANSPORT``,
``set_default_transport()``, or the ``Ros(..., transport=...)`` argument.
* Added transport-parametrized ROS integration tests for CPython, while
keeping IronPython on the ``cli`` transport.

**Changed**

* Updated the package classifiers to 3.9-3.14 (removes most EOL python versions, 3.9 is still supported).

**Fixed**

**Deprecated**
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
graft docs
graft src
graft tests
graft benchmarks

prune docker

include .bumpversion.cfg
include .editorconfig
include .readthedocs.yaml

include AUTHORS.rst
include CHANGELOG.rst
Expand Down
17 changes: 17 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,30 @@ To install **roslibpy**, simply use ``pip``::

pip install roslibpy

The default WebSocket transport on CPython uses Autobahn on the Twisted
reactor. An alternative transport that runs the same Autobahn WebSocket stack
on an asyncio event loop is also available (no extra dependencies required);
see `Transport selection`_ below.

For IronPython, the ``pip`` command is slightly different::

ipy -X:Frames -m pip install --user roslibpy

Remember that you will need a working ROS setup including the
**rosbridge server** and **TF2 web republisher** accessible within your network.

Transport selection
-------------------

CPython uses the ``twisted`` transport by default; IronPython uses ``cli``. The
``asyncio`` transport runs the same Autobahn WebSocket stack on an asyncio
event loop. To select it, either pass it per client, set the process-wide
default, or set the environment variable::

roslibpy.Ros(host='localhost', port=9090, transport='asyncio')
roslibpy.set_default_transport('asyncio')
ROSLIBPY_TRANSPORT=asyncio python my_script.py


Documentation
-------------
Expand Down
Loading
Loading