Getting all field names from a protocol buffer?
Question:
I want to get all the field names of a proto into a list. Is there a way to do this? I looked in the documentation and there doesn’t seem to be anything for this.
Answers:
Every proto class possess a DESCRIPTOR class variable that can be used to inspect the fields of corresponding protobuf messages.
Have a look at the documentation of the Descriptor and FieldDescriptor classes for more details.
Here is a simple example to get the FieldDescriptor
s of all the fields in message
into a list:
res = message.DESCRIPTOR.fields
To get the names of the fields “exactly as they appear in the .proto file”:
res = [field.name for field in message.DESCRIPTOR.fields]
or (from the comments):
res = message.DESCRIPTOR.fields_by_name.keys()
To get the full names of the fields “including containing scope”:
res = [field.full_name for field in message.DESCRIPTOR.fields]
qfiard’s answer didn’t work for me. Calling message.DESCRIPTOR.fields.keys()
produced AttributeError: 'list' object has no attribute 'keys'
.
Not sure why it wouldn’t work. Maybe it has something to do with how the message was defined/compiled.
The workaround was to do a list composition of the individual field objects and get the name
property for each. This gave me a list of strings of all fields in this list.
res = [f.name for f in message.DESCRIPTOR.fields]
Note that this does not get you the field names within those fields recursively.
You can easily get a list of fields as follows
message_fields = [field for field in message.DESCRIPTOR.fields_by_name]
I bumped to Python 3.9 and some of these solutions broke, so I found a solution using the public interface of a message object, not using the DESCRIPTOR
attribute.
fields = [desc.name for desc, val in message.ListFields()]
Note however, this solution will only fetch the fields which have been set.
Doc is here: https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message.ListFields
I want to get all the field names of a proto into a list. Is there a way to do this? I looked in the documentation and there doesn’t seem to be anything for this.
Every proto class possess a DESCRIPTOR class variable that can be used to inspect the fields of corresponding protobuf messages.
Have a look at the documentation of the Descriptor and FieldDescriptor classes for more details.
Here is a simple example to get the FieldDescriptor
s of all the fields in message
into a list:
res = message.DESCRIPTOR.fields
To get the names of the fields “exactly as they appear in the .proto file”:
res = [field.name for field in message.DESCRIPTOR.fields]
or (from the comments):
res = message.DESCRIPTOR.fields_by_name.keys()
To get the full names of the fields “including containing scope”:
res = [field.full_name for field in message.DESCRIPTOR.fields]
qfiard’s answer didn’t work for me. Calling message.DESCRIPTOR.fields.keys()
produced AttributeError: 'list' object has no attribute 'keys'
.
Not sure why it wouldn’t work. Maybe it has something to do with how the message was defined/compiled.
The workaround was to do a list composition of the individual field objects and get the name
property for each. This gave me a list of strings of all fields in this list.
res = [f.name for f in message.DESCRIPTOR.fields]
Note that this does not get you the field names within those fields recursively.
You can easily get a list of fields as follows
message_fields = [field for field in message.DESCRIPTOR.fields_by_name]
I bumped to Python 3.9 and some of these solutions broke, so I found a solution using the public interface of a message object, not using the DESCRIPTOR
attribute.
fields = [desc.name for desc, val in message.ListFields()]
Note however, this solution will only fetch the fields which have been set.
Doc is here: https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message.ListFields