{"id":4982,"library":"mcap-protobuf-support","title":"MCAP Protobuf Support for Python","description":"This package provides Protobuf support for the Python MCAP library, enabling seamless reading and writing of Protobuf-encoded messages to MCAP files. MCAP is a modular, performant, and serialization-agnostic container file format, widely adopted in robotics for pub/sub data logging applications. The library is actively developed and maintained by Foxglove, with regular releases across the broader MCAP ecosystem.","status":"active","version":"0.5.4","language":"en","source_language":"en","source_url":"https://github.com/foxglove/mcap","tags":["mcap","protobuf","serialization","robotics","data logging","foxglove"],"install":[{"cmd":"pip install mcap-protobuf-support","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core Python MCAP library; `mcap-protobuf-support` is a helper library built on top of it.","package":"mcap"},{"reason":"Required for Protobuf message definitions and serialization.","package":"google-protobuf"}],"imports":[{"symbol":"read_protobuf_messages","correct":"from mcap_protobuf.reader import read_protobuf_messages"},{"note":"Older versions (e.g., v0.0.4) and low-level usage might involve manually registering schemas with `mcap.mcap0.writer`. The `mcap_protobuf.writer.Writer` provides a simplified, higher-level API.","wrong":"from mcap.mcap0.writer import Writer as McapWriter; from mcap_protobuf.schema import register_schema","symbol":"Writer","correct":"from mcap_protobuf.writer import Writer"}],"quickstart":{"code":"import sys\nfrom mcap_protobuf.writer import Writer\nfrom mcap_protobuf.reader import read_protobuf_messages\n\n# Assuming you have a compiled protobuf message, e.g., 'my_message_pb2.py'\n# from my_message_pb2 import SimpleMessage, ComplexMessage\n\n# For demonstration, we'll create dummy classes that mimic protobuf messages\nclass SimpleMessage:\n    def __init__(self, data):\n        self.data = data\n    def SerializeToString(self):\n        return f'SimpleMessage(data=\"{self.data}\")'.encode('utf-8') # Dummy serialization\n    @classmethod\n    def FromString(cls, data):\n        # Dummy deserialization - in a real scenario, this would parse protobuf bytes\n        import re\n        match = re.search(r'data=\"([^\"]+)\"', data.decode('utf-8'))\n        return cls(match.group(1)) if match else cls('N/A')\n\nclass ComplexMessage:\n    def __init__(self, fieldA, fieldB):\n        self.fieldA = fieldA\n        self.fieldB = fieldB\n    def SerializeToString(self):\n        return f'ComplexMessage(fieldA=\"{self.fieldA}\", fieldB=\"{self.fieldB}\")'.encode('utf-8') # Dummy serialization\n    @classmethod\n    def FromString(cls, data):\n        # Dummy deserialization\n        import re\n        match = re.search(r'fieldA=\"([^\"]+)\".*fieldB=\"([^\"]+)\"', data.decode('utf-8'))\n        return cls(match.group(1), match.group(2)) if match else cls('N/A', 'N/A')\n\n# To make this runnable without actual .proto compilation, we need to mock\n# how the `Writer` would register these messages. In a real scenario, \n# SimpleMessage and ComplexMessage would be actual protobuf generated classes.\n\n# ---- Writing MCAP file with Protobuf messages ----\noutput_file = \"example.mcap\"\nwith open(output_file, \"wb\") as f, Writer(f) as mcap_writer:\n    # In a real application, SimpleMessage would be from `your_proto_file_pb2`\n    mcap_writer.write_message(\n        topic=\"/simple_messages\",\n        message=SimpleMessage(data=\"Hello MCAP protobuf world #1!\"),\n        log_time=1000,\n        publish_time=1000,\n    )\n    complex_message = ComplexMessage(fieldA=\"Field A 1\", fieldB=\"Field B 1\")\n    mcap_writer.write_message(\n        topic=\"/complex_messages\",\n        message=complex_message,\n        log_time=2000,\n        publish_time=2000,\n    )\nprint(f\"Wrote messages to {output_file}\")\n\n# ---- Reading MCAP file with Protobuf messages ----\ndef register_dummy_message_classes(reader):\n    # This function mocks how actual protobuf message classes would be registered\n    # For real use, you'd import your compiled protobuf message classes\n    reader.register_message(\"SimpleMessage\", SimpleMessage)\n    reader.register_message(\"ComplexMessage\", ComplexMessage)\n\n\nprint(f\"\\nReading messages from {output_file}:\")\nfor msg_info in read_protobuf_messages(output_file):\n    # The msg_info.proto_msg will be an instance of your actual Protobuf class\n    print(f\"Topic: {msg_info.topic}, Message: {msg_info.proto_msg.data if hasattr(msg_info.proto_msg, 'data') else msg_info.proto_msg.fieldA}\")\n\n","lang":"python","description":"This quickstart demonstrates how to write and read Protobuf messages to/from an MCAP file using `mcap-protobuf-support`. Before running, you would typically compile your `.proto` files into Python classes using `protoc` (e.g., `protoc --python_out=. your_message.proto`). The example uses dummy classes to simulate compiled Protobuf messages for executability. The `Writer` automatically handles schema registration, and `read_protobuf_messages` iterates through decoded messages."},"warnings":[{"fix":"Migrate write operations to use `from mcap_protobuf.writer import Writer`. The `Writer` constructor takes a file-like object, and `write_message` directly accepts Protobuf message objects.","message":"The high-level API for writing Protobuf messages to MCAP files has been significantly streamlined. Prior to `mcap-protobuf-support` v0.5.0, users often manually registered schemas using `mcap.mcap0.writer.Writer` and `mcap_protobuf.schema.register_schema`. The current recommended approach uses `mcap_protobuf.writer.Writer`, which abstracts away schema registration, simplifying usage.","severity":"breaking","affected_versions":"<0.5.0"},{"fix":"Run `protoc --python_out=. your_message.proto` to generate `your_message_pb2.py` files. Then, import your message classes from these generated files.","message":"Protobuf message definitions (`.proto` files) must be compiled into Python classes using the `protoc` compiler before they can be used with `mcap-protobuf-support`. The library does not dynamically parse `.proto` files at runtime.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Design Protobuf schemas with compatibility in mind (e.g., avoid changing field numbers, make new fields optional, avoid removing fields). Test schema evolution thoroughly across different versions of your data and code.","message":"While MCAP itself supports schema evolution, managing changes to Protobuf message schemas requires adherence to Protobuf's own forward and backward compatibility rules. Incompatible schema changes can lead to deserialization errors when reading older or newer MCAP files.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}