{"id":10023,"library":"pbtools","title":"Google Protocol Buffers Tools","description":"`pbtools` is a Python library for working with Google Protocol Buffers. It provides tools to read, write, encode, and decode Protocol Buffers messages (both binary and text) directly from `.proto` definitions, *without* requiring generated Python code. This simplifies field access and enables decoding of unknown messages. The current version is 0.47.0, and it maintains an active release cadence with incremental updates.","status":"active","version":"0.47.0","language":"en","source_language":"en","source_url":"https://github.com/eerimoq/pbtools","tags":["protobuf","protocol buffers","serialization","data exchange","data formats"],"install":[{"cmd":"pip install pbtools","lang":"bash","label":"Install pbtools"}],"dependencies":[{"reason":"Required for parsing `.proto` files and handling Protocol Buffers message structures. `pbtools` builds upon the core `protobuf` library.","package":"protobuf","optional":false}],"imports":[{"symbol":"build_database","correct":"from pbtools import build_database"},{"symbol":"Database","correct":"from pbtools import Database"},{"symbol":"Message","correct":"from pbtools import Message"},{"symbol":"Field","correct":"from pbtools import Field"}],"quickstart":{"code":"import pbtools\nimport os\n\n# Example .proto file content\nproto_file_content = \"\"\"\nsyntax = \"proto3\";\n\nmessage MyMessage {\n    int32 id = 1;\n    string name = 2;\n    repeated int32 values = 3;\n}\n\"\"\"\n# For simplicity, write to a temporary file\nproto_path = \"my_message.proto\"\nwith open(proto_path, \"w\") as f:\n    f.write(proto_file_content)\n\n# Build a database from .proto files\ndatabase = pbtools.build_database([proto_path])\n\n# Get the message type from the database\nMyMessage = database.MyMessage\n\n# Create a message instance\nmessage = MyMessage(id=1, name=\"hello\", values=[10, 20, 30])\nprint(f\"Original message: {message}\")\n\n# Encode to binary\nencoded = message.encode()\nprint(f\"Encoded bytes: {encoded}\")\n\n# Decode from binary\ndecoded = MyMessage.decode(encoded)\nprint(f\"Decoded message: {decoded}\")\n\n# Access fields\nprint(f\"Decoded ID: {decoded.id}\")\nprint(f\"Decoded Name: {decoded.name}\")\nprint(f\"Decoded Values: {decoded.values}\")\n\n# Clean up the temporary file\nos.remove(proto_path)","lang":"python","description":"This quickstart demonstrates how to define a Protocol Buffer message, build a database from its `.proto` definition, create a message instance, encode it to binary, and then decode it back using `pbtools`. It highlights the direct interaction with messages without code generation."},"warnings":[{"fix":"Understand that `pbtools` dynamically works with message definitions by parsing `.proto` files at runtime, offering a different paradigm than compiled protobuf code. It's designed for direct data manipulation.","message":"`pbtools` explicitly avoids generating Python code, which is a common workflow for `protoc`. Users accustomed to `protoc`-generated classes might find this approach different. `pbtools` parses `.proto` files at runtime.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Usually handled automatically by `pip install pbtools`. If issues arise, check `pip check` and ensure there are no conflicting `protobuf` installations or manual downgrades of `protobuf`.","message":"Although `pbtools` does not generate code, it still relies on the core `protobuf` library for its underlying mechanisms. Ensure the `protobuf` package is installed and compatible with your `pbtools` version (e.g., `pbtools` 0.47.0 requires `protobuf>=4.0.0`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be aware of Protobuf's default value behavior. For optional fields or fields that might genuinely be missing, consider checking if the field was 'set' if such a feature becomes available or design your `.proto` schema accordingly.","message":"When accessing fields on a decoded message, if a field is not present in the binary data, `pbtools` will return its default value (e.g., `0` for integers, `''` for strings, empty list for repeated fields) rather than raising an `AttributeError`. This can mask missing data if not explicitly checked.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Run `pip install pbtools` to install the library. If using a virtual environment, ensure it is activated.","cause":"The `pbtools` package is not installed in the current Python environment, or the environment is not activated.","error":"ModuleNotFoundError: No module named 'pbtools'"},{"fix":"Verify that the message name exactly matches the definition in your `.proto` file and that all necessary `.proto` files are included in the list passed to `build_database()`.","cause":"The message type specified (e.g., `database.MyMessage`) does not exist in any of the `.proto` files provided to `pbtools.build_database()`, or there is a typo in the message name.","error":"pbtools.error.Error: Failed to find message 'MyMessage'."},{"fix":"Ensure that the Python data types used when creating a message instance match the corresponding Protobuf field types (e.g., `int` for `int32`, `str` for `string`, `list` for `repeated`). Verify the integrity of binary data before decoding.","cause":"Attempting to assign a Python type that is incompatible with the declared Protobuf field type (e.g., passing a `bytes` object to an `int32` field), or trying to decode malformed binary data.","error":"TypeError: 'bytes' object cannot be interpreted as an integer"},{"fix":"Access specific message types as attributes of the `Database` object (e.g., `database.MyMessage`) to create or decode message instances.","cause":"The `Database` object returned by `build_database()` is a container for message *types*, not a collection of message *instances*. It cannot be directly iterated over.","error":"TypeError: argument of type 'Database' is not iterable"}]}