Here is a working example as well as reproducing the exception above.
Step 1: todolist.proto file with following content:
syntax = "proto3"; // Not necessary for Python but should still be declared to avoid name collisions // in the Protocol Buffers namespace and non-Python languages package protoblog; // Style guide prefers prefixing enum values instead of surrounding // with an enclosing message enum TaskState { TASK_OPEN = 0; TASK_IN_PROGRESS = 1; TASK_POST_PONED = 2; TASK_CLOSED = 3; TASK_DONE = 4; } message TodoList { int32 owner_id = 1; string owner_name = 2; message ListItems { TaskState state = 1; string task = 2; string due_date = 3; } repeated ListItems todos = 3; }
Step 2: Generate python specific code from todolist.proto file by running following:
protoc -I=. --python_out=. todolist.proto
This will generate a file in the current directory todolist_pb2.py
Step 3: Create a python project and copy todolist_pb2.py to it.
Step 4: Create a python module proto_test.py with following content:
import json from google.protobuf.json_format import Parse from google.protobuf.json_format import MessageToDict from todolist_pb2 import TodoList todolist_json_message = { "ownerId": "1234", "ownerName": "Tim", "todos": [ { "state": "TASK_DONE", "task": "Test ProtoBuf for Python", "dueDate": "31.10.2019" } ] } todolist_proto_message = Parse(json.dumps(todolist_json_message), TodoList()) print(todolist_proto_message) # Successfully converts the message to dictionary todolist_proto_message_dict = MessageToDict(todolist_proto_message) print(todolist_proto_message_dict) # If you try to convert a field from your message rather than entire message, # you will get object has no attribute 'DESCRIPTOR exception' # Examples: # Eg.1: Produces AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute # 'DESCRIPTOR.' todos_as_dict = MessageToDict(todolist_proto_message.todos) # Eg.2: Produces AttributeError: 'int' object has no attribute 'DESCRIPTOR' owner_id_as_dict = MessageToDict(todolist_proto_message.owner_id)
Step 5: Run the proto_test.py module and you can see the failing behavior and the successful behavior.
So it seems like you are not converting your actual message rather you are converting a field of type list from your message/response. So try to convert the entire message and then retrieve the field you are interested in.
Please let me know if it helps.
NOTE: You need to ensure protoc compiler is installed in your machine to compile .proto file to python specific code as mentioned in step 2. Installation instruction can be found below: MacOS/Linux
Windows
from google.protobuf.json_format import MessageToDictdict_obj = MessageToDict(message_obj)@PirateNinjas