Closed inska closed 4 years ago
@inska Can you provide a code snippet that produces the thing you'd like to serialize?
@inska Sadly, the objects in the current Vision library lack serialization functions (although this is a good idea).
It is worth noting that we are about to release a substantially different library for Vision (it is on master of this repo now, although not released to PyPI yet) where this will be possible. Note that it is a backwards-incompatible upgrade, so there will be some (hopefully not too much) conversion effort.
That library returns plain protobuf objects, which can be serialized to JSON using:
from google.protobuf.json_format import MessageToJson
serialized = MessageToJson(original)
You can also go to dictionaries using something like protobuf3-to-dict.
P. S. I am going to go ahead and close this issue, since I hope I have answered it, but please feel free to reopen if needed!
Hi @lukesneeringer , I have tried it but it return an error like: AttributeError:'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'DESCRIPTOR'
How can I resolve this error?
@lukesneeringer same problem with @arycloud AttributeError:'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'DESCRIPTOR'
Thanks @lukesneeringer
I can't believe how many google searches it took me to find the answer you posted.
@arycloud @u2takey I had the same problem as you and I realized it's because I "unpack" the response before trying to convert it to json or dict. For example:
response = client.annotate_image({'image': {'source': {'image_uri': image_url}}, 'features': features, })
My program did the equivalent of:
MessageToJson(response.label_annotation)
, which results in AttributeError:'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'DESCRIPTOR'
Now I do:
response = MessageToDict(response, preserving_proto_field_name = True)
desired_res = response["label_annotation"]
Thanks @lukesneeringer
I was befuddled by the same problem when working with Google Cloud Speech-to-Text API. I tried to serialize google.cloud.speech.v1.SpeechRecognitionResult
, but only to find
TypeError: Object of type RepeatedCompositeFieldContainer is not JSON serializable
.
I tried @lukesneeringer 's solution. It works!
Cool. Thank you @lukesneeringer !
Thanks @lukesneeringer
I can't believe how many google searches it took me to find the answer you posted.
Thanks a lot @lukesneeringer ! @rootVIII: I can sooo relate.
Hi @lukesneeringer I was actually using ImageAnnotatorClient with dask for parallel computation. Until now I was just making new ImageAnnotatorClient for each image which is cause memory overflow issue. So I was planning on creating a single instance of ImageAnnotatorClient object and getting all the work done.But with dask client.map method I am unable to serialize the ImageAnnotatorClient object.So is there a way I can serialize it and the deserialize it. I tried the above method but it does not work.
It is not working again. I am still facing this Descriptor error.
All the python client libraries have been given their own repositories and no longer live under google-cloud-python. Transferring to Vision API repo.
There has been another backwards incompatible change with the Vision client library. All message types are now defined using proto-plus, which uses different methods for serialization and deserialization.
In order to get json from a message, do the following:
my_message = MyMessageType(attribute=value)
json_string = MyMessageType.to_json(my_message)
# Also works
json_string = type(my_message).to_json(my_message)
# Also also works
import proto
json_string = proto.Message.to_json(my_message)
This is not a method on the instance but instead a class method of the metaclass.
@software-dov where does MyMessageType come from?
import proto json_string = proto.Message.to_json(my_message) worked for me, thanks @software-dov
@zyfang It's an example type from one of the Cloud APIs. Let's tie the example back into Vision:
from google.cloud.vision import AnnotateFileRequest
request = AnnotateFileRequest()
# Do things with the fields in request.
json_string = AnnotateFileRequest.to_json(request)
I am still getting the error even after following all the above commands. Isn't there any way to extract components from "google.protobuf.pyext._message.RepeatedCompositeCo" object?
@jaihonikhil Once you get your response, you can get the wanted attribute, iterate over it and use the method MessageToDict
on each of the elements.
It seems we now have to access the elements via their attribute "_pb" to make the method work. Here is an example :
from google.protobuf.json_format import MessageToDict
response = my_google_vision_client.label_detection(image=my_image)
tags = response.label_annotations
serializable_tags = [MessageToDict(tag._pb) for tag in tags]
The Proto Plus documentation describes this in a more idiomatic way: https://proto-plus-python.readthedocs.io/en/stable/messages.html#serialization The following should work:
import proto
response = client.label_detection(image=my_image)
serializable_tags = [proto.Message.to_dict(tag) for tag in response.label_annotations]
Just in case 1) you come to this closed issue after Nov 30, 2021, and 2) try out all code snippets that you can find on the internet but still couldn't get it work...
This works for me:
from google.cloud import speech_v1 as speech
config = ...
audio = ...
client = speech.SpeechClient()
operation = client.long_running_recognize(config=config, audio=audio)
op_result = operation.result()
##############
# Okay, fun part -
##############
result_in_dict = json.loads(type(op_result).to_json(op_result))
This works for me
import proto
response = client.label_detection(image=my_image)
serializable_tags = [proto.Message.to_dict(tag) for tag in response.label_annotations]
I recently ran into the same issue for the Google Ads API but I used the MessageToDict method instead and extended it using a generator:
from google.protobuf.json_format import MessageToDict
def get_data():
response = # Make request to API
for row in response.results:
yield MessageToDict(row)
for data in get_data():
# Do something with the data
I find it a lot easier to work with the records in a dictionary format further down the line.
Hi,
Google Cloud SDK works well to get annotation responses via vision API, and I just like to know how can I serialize the response. Is there any helper or serializer for Google response objects? Otherwise, should I parse and build dictionaries from the response object by manual?
python --version
2.7.13pip show google-cloud
,pip show google-<service>
orpip freeze
157.0.0