Skip to content

Protobuf

Protobuf is a message definition language with corresponding tools to facilitate message serialization/deserialization (serdes) with comprehensive support across numerous languages.

Quick Start

Generate Code

Use the protoc tool to generate the protobuf python code that defines the message classes:

protoc --proto_path=/path/to/my/protos --python_out=generated/ my.proto

Pro Tip

Generate type information for generated python code by installing the mypy-protobuf package with

pip install mypy-protobuf
and rerun the code generator like so:
protoc --proto_path=/path/to/my/protos --python_out=generated/ --mypy_out=generated/ my.proto

Basic Usage

from zeloscloud.codecs.proto import Proto

"""
Assumes a generated message defined in a .proto file like so:

message MyMessage {
    string my_signal = 1;
}
"""
from .generated import MyMessage

with Proto("proto") as proto:
    my_message = MyMessage()
    my_message.my_signal = "hello_world"
    proto.trace(name="my_message", message=my_message)

Message Handling Example

from zeloscloud.codecs.proto import Proto, ProtoMessage

# Create a Proto codec instance
with Proto("my_proto") as proto:
    # Create a message
    message = ProtoMessage("request")
    message.update({"field1": "value1", "field2": 42})

    # trace the message
    proto.trace(message, "my_request")

    # Access message data
    data = message.to_dict()
    print(f"Message data: {data}")

Working with Complex Messages

from zeloscloud.codecs.proto import Proto
from my_generated_pb2 import ComplexMessage

with Proto("proto") as proto:
    # Create a complex message
    message = ComplexMessage()
    message.string_field = "test"
    message.repeated_field.extend([1, 2, 3])
    message.nested_message.field = "nested"

    # trace with custom conversion options
    proto.trace(
        message,
        "complex_message",
        conversion_strategy={
            "preserving_proto_field_name": True,
            "including_default_value_fields": True
        }
    )

Parameters and Initialization

Proto Class

  • name: A string representing the name of your Proto instance.
  • config: Contains the config describing how to convert signals by default
    • conversion_strategy: The args to forward to MessageToDict
      • preserving_proto_field_name: Keep original protobuf field names
      • including_default_value_fields: Include fields with default values
      • use_integers_for_enums: Use integers instead of enum names
      • float_precision: Number of decimal places for floats

ProtoMessage Class

  • name: Name of the message
  • message: Optional protobuf message instance
  • conversion_strategy: Optional dictionary of conversion options

Message Conversion

The Proto codec supports flexible message conversion strategies:

# Default conversion (camelCase, no defaults)
proto.trace(message, "default_conversion")

# Preserve protobuf field names
proto.trace(message, "preserved_names",
    conversion_strategy={"preserving_proto_field_name": True})

# Include default values
proto.trace(message, "with_defaults",
    conversion_strategy={"including_default_value_fields": True})

# Custom float precision
proto.trace(message, "precise_floats",
    conversion_strategy={"float_precision": 3})

Troubleshooting

Versioning

The protoc version and the installed protobuf package should be compatible with one another. Check your installed protoc vs chosen protobuf package:

# Check protoc version
protoc --version

# Check protobuf package version
pip show protobuf

Common Issues

  1. Import Errors: Ensure your generated code is in the Python path
  2. Type Errors: Make sure you're using compatible mypy-protobuf versions
  3. Conversion Errors: Check that your conversion strategy matches your message structure

Additional Resources

API Reference

See zeloscloud.codecs.proto.Proto in the API Reference.