A Python library to work with bag files without ROS.
Project description
pybag
A Python library to work with bag files (MCAP and ROS Bag) without ROS.
[!Warning] The library is still in the early stages of development and the API is still unstable
Installation
# Add dependency to your package
uv add pybag-sdk
# Install pybag cli
uv tool install pybag-sdk
Reading Files
There are a number of ways to read data with pybag.
Unified Reader
The Reader class provides a common interface for reading both MCAP and ROS 1 bag files.
The file format is automatically detected from the file extension.
from pybag import Reader
# Works with both .mcap and .bag files
with Reader.from_file("data.mcap") as reader:
for msg in reader.messages("/camera"):
print(msg.log_time, msg.data)
# Same API for ROS 1 bag files
with Reader.from_file("data.bag") as reader:
for msg in reader.messages("/sensor/*"): # glob patterns supported
print(msg.topic, msg.msg_type, msg.data)
Reading MCAP Files
from pybag.mcap_reader import McapFileReader
with McapFileReader.from_file("data.mcap") as reader:
# Get available topics
topics = reader.get_topics()
# Stream messages with filtering
for msg in reader.messages(
topic=["/camera/*", "/sensor/imu"],
start_time=1_000_000_000, # nanoseconds
end_time=2_000_000_000,
in_log_time_order=True
):
print(msg.log_time, msg.data)
# Get attachments and metadata
attachments = reader.get_attachments()
metadata = reader.get_metadata()
Reading ROS 1 Bag Files
from pybag.bag_reader import BagFileReader
with BagFileReader.from_file("data.bag") as reader:
for msg in reader.messages("/camera"):
print(msg.log_time, msg.data)
Writing Files
There are a number of ways to write data with pybag.
Writing MCAP Files
from pybag.mcap_writer import McapFileWriter
from pybag.ros2.humble import std_msgs
with McapFileWriter.open(
"output.mcap",
profile="ros2",
chunk_compression="lz4"
) as writer:
msg = std_msgs.String(data="hello")
writer.write_message("/status", 1_000_000_000, msg)
# Add attachments
writer.write_attachment(
name="calibration.yaml",
data=b"camera: ...",
media_type="application/yaml"
)
# Add metadata
writer.write_metadata("recording_info", {"robot": "husky_1"})
Writing ROS 1 Bag Files
from pybag.bag_writer import BagFileWriter
from pybag.ros1.noetic import std_msgs
with BagFileWriter.open("output.bag", compression="bz2") as writer:
msg = std_msgs.String(data="hello")
writer.write_message("/status", 1_000_000_000, msg)
Append Mode
Both MCAP and bag writers support append mode to add messages to existing files.
Appending to MCAP Files
from pybag.mcap_writer import McapFileWriter
# Create a new file
with McapFileWriter.open("recording.mcap") as writer:
writer.write_message("/topic", 1_000_000_000, msg1)
# Append to existing file
with McapFileWriter.open("recording.mcap", mode="a") as writer:
writer.write_message("/topic", 2_000_000_000, msg2)
writer.write_message("/new_topic", 3_000_000_000, msg3)
Appending to ROS 1 Bag Files
from pybag.bag_writer import BagFileWriter
# Create a new file
with BagFileWriter.open("recording.bag") as writer:
writer.write_message("/topic", 1_000_000_000, msg1)
# Append to existing file
with BagFileWriter.open("recording.bag", mode="a") as writer:
writer.write_message("/topic", 2_000_000_000, msg2)
writer.write_message("/new_topic", 3_000_000_000, msg3)
TypeStore
The TypeStore provides unified access to ROS message schemas from built-in definitions
and custom .msg files.
from pybag.typestore import TypeStore
# Create a type store for ROS 2 Humble
type_store = TypeStore(encoding="ros2msg", distro="humble")
# Add custom message paths
type_store.add_path("/path/to/custom_msgs")
# Find a message schema
schema = type_store.find("std_msgs/msg/String")
# List user-provided messages
messages = type_store.list_messages()
Supported Distributions
ROS 1: noetic (and legacy: melodic, kinetic, indigo, etc.)
ROS 2: foxy, galactic, humble, iron, jazzy, kilted, rolling
Custom Messages
Define custom message types using dataclasses:
from dataclasses import dataclass
import pybag.types as t
from pybag.mcap_writer import McapFileWriter
@dataclass
class SensorData:
__msg_name__ = "custom/msg/SensorData"
temperature: t.float32
humidity: t.float32
with McapFileWriter.open("sensors.mcap") as writer:
writer.write_message("/sensor", 1_000_000_000, SensorData(25.5, 60.0))
Or provide schema text directly:
from pybag.types import SchemaText
schema = SchemaText(
name="custom/msg/SensorData",
text="float32 temperature\nfloat32 humidity"
)
with McapFileWriter.open("sensors.mcap") as writer:
writer.add_channel("/sensor", schema=schema)
writer.write_message("/sensor", 1_000_000_000, {"temperature": 25.5, "humidity": 60.0})
CLI Reference
info
Display file statistics and metadata:
pybag info recording.mcap
pybag info recording.bag
filter
Extract data based on topic patterns and time ranges:
pybag filter input.mcap -o output.mcap \
--include-topic "/sensor/*" \
--exclude-topic "/sensor/debug" \
--start-time 10.5 \
--end-time 20.3
merge
Combine multiple files into one:
pybag merge file1.mcap file2.mcap -o merged.mcap
pybag merge bag1.bag bag2.bag -o merged.bag
convert
Convert between bag and MCAP formats:
# Bag to MCAP
pybag convert input.bag -o output.mcap --profile ros2 --mcap-compression lz4
# MCAP to Bag
pybag convert input.mcap -o output.bag --bag-compression bz2
sort
Sort messages by time and/or topic:
pybag sort input.mcap -o sorted.mcap --log-time --by-topic
recover
Recover data from corrupted files:
pybag recover corrupted.mcap -o recovered.mcap --verbose
inspect
Examine specific record types:
pybag inspect schemas recording.mcap
pybag inspect channels recording.mcap --topic "/camera/*"
pybag inspect metadata recording.mcap --name "calibration"
pybag inspect attachments recording.mcap --name "calib.yaml" --data
event
Manage events in MCAP files.
Events are markers that indicate when something significant happens in the recording (e.g., collisions, waypoints, incidents). Events are stored as metadata records.
List events:
pybag event list recording.mcap
pybag event list recording.mcap --name "collision"
pybag event list recording.mcap --json
Add events:
By default, events are appended to the MCAP in place.
Use -o to copy the MCAP and add the event to the copy instead.
# Append in place (default)
pybag event add recording.mcap "collision" 10.5
pybag event add recording.mcap "start" 0.0 --description "Recording started"
pybag event add recording.mcap "waypoint" 25.0 --extra waypoint_id=42
# Copy mode: add event to a new copy
pybag event add recording.mcap "collision" 10.5 -o with_event.mcap
Delete events:
Use -o to copy the MCAP and hard delete (remove) the events from the copy.
pybag event delete recording.mcap --name "collision" -o cleaned.mcap
pybag event delete recording.mcap --start-time 5.0 --end-time 10.0 -o cleaned.mcap
Clip around an event:
Extract a portion of the recording relative to an event's timestamp:
# Symmetric: 5s before AND after the event
pybag event clip recording.mcap "collision" --margin 5
# Before only: from (event_time - 3s) to event_time
pybag event clip recording.mcap "end" --before 3
# After only: from event_time to (event_time + 10s)
pybag event clip recording.mcap "start" --after 10
# Asymmetric: 5s before and 10s after
pybag event clip recording.mcap "incident" --before 5 --after 10
# With topic filtering
pybag event clip recording.mcap "crash" --margin 5 --include-topic "/camera/*" -o clip.mcap
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pybag_sdk-0.13.0.tar.gz.
File metadata
- Download URL: pybag_sdk-0.13.0.tar.gz
- Upload date:
- Size: 292.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9f8b7aa09f118469cf5d36a2141572f2a818a72d2cc7ac96bc0bc31ff2ee07c
|
|
| MD5 |
9475ff9ebdf4ec48bed26e2c4dbdfa53
|
|
| BLAKE2b-256 |
b657e4f0003e17e6dc85a767d5c41cc4237cac7f3c5736eebdb7c504ba583c42
|
File details
Details for the file pybag_sdk-0.13.0-py3-none-any.whl.
File metadata
- Download URL: pybag_sdk-0.13.0-py3-none-any.whl
- Upload date:
- Size: 202.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
352b677d60c6050506f355ac465235d9dd9cf50605780acf3dcd78690f4fe527
|
|
| MD5 |
8a4e7b2f4bd79d8ecc4940b71138670b
|
|
| BLAKE2b-256 |
ea155e0dd9ea3e1f838793c3687fe9b46ee04703f34b77b2420db589b3d2f62d
|