protobuf - Registry for Google Protocol Buffer messages and enums¶
Overview¶
This module provides a central registry for Google Protocol Buffer message types
and enum types generated from proto files. It allows creating message instances
and accessing enum information using their fully qualified names (e.g.,
“my.package.MyMessage”, “my.package.MyEnum”) without needing to directly import
the corresponding generated _pb2.py modules throughout the codebase.
Benefits:
Decouples code using protobuf messages from the specific generated modules.
Provides a single point for managing and discovering available message/enum types.
Facilitates dynamic loading of protobuf definitions via entry points.
Core Features:
Register message/enum types using their file DESCRIPTOR object.
Create new message instances by name using
create_message().Access enum descriptors and values by name using
get_enum_type().Load protobuf definitions registered by other installed packages via entry points using
load_registered().Helpers for common types like
google.protobuf.Struct.
Example:
# Assume you have my_proto_pb2.py generated from my_proto.proto
# containing:
# message Sample { required string name = 1; }
# enum Status { UNKNOWN = 0; OK = 1; ERROR = 2; }
from firebird.base.protobuf import (
register_descriptor, create_message, get_enum_type, is_msg_registered
)
# Import the generated descriptor (only needed once, e.g., at startup)
try:
from . import my_proto_pb2 # Replace with actual import path
HAS_MY_PROTO = True
except ImportError:
HAS_MY_PROTO = False
# 1. Register the types from the descriptor
if HAS_MY_PROTO:
register_descriptor(my_proto_pb2.DESCRIPTOR)
print(f"Is 'my_proto.Sample' registered? {is_msg_registered('my_proto.Sample')}")
# 2. Create a message instance by name
if HAS_MY_PROTO:
try:
msg = create_message('my_proto.Sample')
msg.name = "Example"
print(f"Created message: {msg}")
# 3. Access enum type and values by name
status_enum = get_enum_type('my_proto.Status')
print(f"Status enum name: {status_enum.name}")
print(f"OK value: {status_enum.OK}") # Access like attribute
print(f"Name for value 2: {status_enum.get_value_name(2)}") # Access via method
print(f"Available status keys: {status_enum.keys()}")
except KeyError as e:
print(f"Error accessing registered proto type: {e}")
Constants¶
- firebird.base.protobuf.PROTO_EMPTY: str = 'google.protobuf.Empty'¶
Name of well-known EMPTY protobuf message (for use with
create_message())
- firebird.base.protobuf.PROTO_ANY: str = 'google.protobuf.Any'¶
Name of well-known ANY protobuf message (for use with
create_message())
- firebird.base.protobuf.PROTO_DURATION: str = 'google.protobuf.Duration'¶
Name of well-known DURATION protobuf message (for use with
create_message())
- firebird.base.protobuf.PROTO_TIMESTAMP: str = 'google.protobuf.Timestamp'¶
Name of well-known TIMESTAMP protobuf message (for use with
create_message())
- firebird.base.protobuf.PROTO_STRUCT: str = 'google.protobuf.Struct'¶
Name of well-known STRUCT protobuf message (for use with
create_message())
- firebird.base.protobuf.PROTO_VALUE: str = 'google.protobuf.Value'¶
Name of well-known VALUE protobuf message (for use with
create_message())
- firebird.base.protobuf.PROTO_LISTVALUE: str = 'google.protobuf.ListValue'¶
Name of well-known LISTVALUE protobuf message (for use with
create_message())
- firebird.base.protobuf.PROTO_FIELDMASK: str = 'google.protobuf.FieldMask'¶
Name of well-known FIELDMASK protobuf message (for use with
create_message())
Functions¶
- firebird.base.protobuf.register_decriptor(file_descriptor) None[source]¶
Register all message and enum types defined within a protobuf file descriptor.
This is the primary mechanism for adding types to the registry. The descriptor object is typically accessed as
DESCRIPTORfrom a generated_pb2.pymodule.- Parameters:
file_descriptor – The
google.protobuf.descriptor.FileDescriptorobject (e.g.,my_proto_pb2.DESCRIPTOR).- Return type:
None
- firebird.base.protobuf.load_registered(group: str) None[source]¶
Load and register protobuf types defined via package entry points.
Searches for installed packages that register entry points under the specified
group. Each entry point should load aFileDescriptorobject. This allows packages to automatically make their protobuf types available to the registry upon installation.This function is typically called once during application initialization.
- Parameters:
group (str) – The name of the entry-point group to scan (e.g., ‘firebird.base.protobuf’).
- Return type:
None
Example
# setup.cfg: [options.entry_points] firebird.base.protobuf = firebird.base.lib_a = firebird.base.lib_a_pb2:DESCRIPTOR firebird.base.lib_b = firebird.base.lib_b_pb2:DESCRIPTOR firebird.base.lib_c = firebird.base.lib_c_pb2:DESCRIPTOR # pyproject.toml [project.entry-points."firebird.base.protobuf"] "firebird.base.lib_a" = "firebird.base.lib_a_pb2:DESCRIPTOR" "firebird.base.lib_b" = "firebird.base.lib_b_pb2:DESCRIPTOR" "firebird.base.lib_c" = "firebird.base.lib_c_pb2:DESCRIPTOR"
Usage:
# In your application's startup code: load_registered('firebird.base.protobuf') # Now messages/enums registered via entry points are available
- firebird.base.protobuf.is_msg_registered(name: str) bool[source]¶
Check if a protobuf message type with the given name is registered.
- firebird.base.protobuf.is_enum_registered(name: str) bool[source]¶
Check if a protobuf enum type with the given name is registered.
- firebird.base.protobuf.get_enum_type(name: str) ProtoEnumType[source]¶
Return the
ProtoEnumTypewrapper for a registered enum type by name.Provides access to enum members and values via the wrapper object.
- Parameters:
type. (Fully qualified name of the registered protobuf enum) –
name (str) –
- Returns:
The
ProtoEnumTypeinstance for the requested enum.- Raises:
KeyError – If
namedoes not correspond to a registered enum type.- Return type:
- firebird.base.protobuf.get_enum_value_name(enum_type_name: str, value: int) str[source]¶
Return the string name corresponding to a value within a registered enum type.
Convenience function equivalent to
get_enum_type(enum_type_name).get_value_name(value).
- firebird.base.protobuf.create_message(name: str, serialized: bytes | None = None) Message[source]¶
Create a new instance of a registered protobuf message type by name.
Optionally initializes the message by parsing serialized data.
- Parameters:
- Returns:
An instance of the requested protobuf message class.
- Raises:
KeyError – If
namedoes not correspond to a registered message type.google.protobuf.message.DecodeError – If
serializeddata is provided but cannot be parsed correctly for the message type.
- Return type:
Message
- firebird.base.protobuf.get_enum_field_type(msg, field_name: str) str[source]¶
Return the fully qualified name of the enum type for a message field.
- Parameters:
msg – An instance of a protobuf message.
field_name (str) – The string name of the field within the message.
- Returns:
The fully qualified name of the enum type used by the field.
- Raises:
- Return type:
Data classes¶
- class firebird.base.protobuf.ProtoMessageType(name: str, constructor: Callable)[source]¶
Bases:
DistinctRegistry entry representing a registered Protocol Buffer message type.
Stores the fully qualified name and the constructor (the generated class) for a message type, allowing instantiation via the registry.
- Parameters:
- class firebird.base.protobuf.ProtoEnumType(descriptor: EnumDescriptor)[source]¶
Bases:
DistinctRegistry entry providing access to a registered Protocol Buffer enum type.
Wraps the
EnumDescriptorand provides an API similar to generated enum types, allowing access to names and values without direct import of the generated_pb2module.- Parameters:
descriptor (EnumDescriptor) – The
google.protobuf.descriptor.EnumDescriptorfor the enum type.
Example:
# Assuming 'my_proto.Status' enum (UNKNOWN=0, OK=1) is registered status_enum = get_enum_type('my_proto.Status') print(status_enum.OK) # Output: 1 (Access value by name) print(status_enum.get_value_name(1)) # Output: 'OK' (Get name by value) print(status_enum.keys()) # Output: ['UNKNOWN', 'OK'] print(status_enum.values()) # Output: [0, 1] print(status_enum.items()) # Output: [('UNKNOWN', 0), ('OK', 1)] try: print(status_enum.NONEXISTENT) except AttributeError as e: print(e) # Output: Enum my_proto.Status has no value with name 'NONEXISTENT' try: print(status_enum.get_value_name(99)) except KeyError as e: print(e) # Output: "Enum my_proto.Status has no name defined for value 99"
- __getattr__(name: str)[source]¶
Return the integer value corresponding to the enum member name
name.- Parameters:
name (str) – The string name of the enum member.
- Returns:
The integer value of the enum member.
- Raises:
AttributeError – If
nameis not a valid member name for this enum.
- get_value_name(number: int) str[source]¶
Return the string name corresponding to the enum member value
number.
- items() list[tuple[str, int]][source]¶
Return a list of the (name, value) pairs of the enum.
These are returned in the order they were defined in the .proto file.
- keys() list[str][source]¶
Return a list of the string names in the enum.
These are returned in the order they were defined in the .proto file.
- values() list[int][source]¶
Return a list of the integer values in the enum.
These are returned in the order they were defined in the .proto file.
- descriptor: EnumDescriptor¶
The
google.protobuf.descriptor.EnumDescriptorfor the enum type.