Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pybag_sdk-0.13.0.tar.gz (292.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pybag_sdk-0.13.0-py3-none-any.whl (202.6 kB view details)

Uploaded Python 3

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

Hashes for pybag_sdk-0.13.0.tar.gz
Algorithm Hash digest
SHA256 e9f8b7aa09f118469cf5d36a2141572f2a818a72d2cc7ac96bc0bc31ff2ee07c
MD5 9475ff9ebdf4ec48bed26e2c4dbdfa53
BLAKE2b-256 b657e4f0003e17e6dc85a767d5c41cc4237cac7f3c5736eebdb7c504ba583c42

See more details on using hashes here.

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

Hashes for pybag_sdk-0.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 352b677d60c6050506f355ac465235d9dd9cf50605780acf3dcd78690f4fe527
MD5 8a4e7b2f4bd79d8ecc4940b71138670b
BLAKE2b-256 ea155e0dd9ea3e1f838793c3687fe9b46ee04703f34b77b2420db589b3d2f62d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page