How To Convert Google Client Vision Library Response To Json
Asked Answered
A

2

5

I am trying to convert the response from Google Cloud Vision API Client Library to a json format. However i get the following error:

AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'DESCRIPTOR

Resource

from flask_restful import Resource
from flask import request
from flask import json
from util.GoogleVision import GoogleVision
from util.Convert import Convert

import base64
import requests

import os


class Vision(Resource):

    def post(self):

        googleVision = GoogleVision()

        req = request.get_json()

        url = req['url']

        result = googleVision.detectLabels(url)

        return result

GoogleVision.py

import os

from google.cloud import vision
from google.cloud.vision import types
from google.protobuf.json_format import MessageToJson

class GoogleVision():

    def detectLabels(self, uri):

        client = vision.ImageAnnotatorClient()
        image = types.Image()
        image.source.image_uri = uri

        response = client.label_detection(image=image)
        labels = response.label_annotations

        res = MessageToJson(labels)

        return res

the labels variable is of type <class'google.protobuf.pyext._message.RepeatedCompositeContainer'>

As you can see i am using message to json function on the labels response. But i am getting the above error.

Is there a way to convert the result to a json format?

Acerate answered 15/6, 2018 at 11:3 Comment(3)
khan, can you attach the whole code & complete error instead of a line. The current attached error says about "DESCRIPTOR" which is not used any where abovePyrognostics
@UdayS this is the whole codeAcerate
Why don't you use the API Discovery? Look at this example on how to use it with this API.Koziara
L
8

A simple way to do it is using the Discovery API. You can create a service object using the build() function. You will get the response as a dictionary when executing the request. Then you can convert it to JSON using json.dumps().

Example with Discovery API:

import json
import apiclient.discovery
import base64

class GoogleVision():

    def detectLabels(self, uri):

        # Instantiates a client
        service = apiclient.discovery.build('vision', 'v1')

        # Image file
        file_name=uri

        # Loads the image into memory
        with open(file_name, 'rb') as image:
            image_content = base64.b64encode(image.read())

            # Creates the request
            service_request = service.images().annotate(body={
                'requests': [{
                    'image': {
                        'content': image_content.decode('UTF-8')
                    },
                    'features': [{
                        'type': 'LABEL_DETECTION',
                    }]
                }]
            })

        # Execute the request  
        response = service_request.execute()

        # Convert to Json
        res_json = json.dumps(response)

        return res_json

If you don’t want to use the Discovery API, you can convert the response to dictionary using MessageToDict() function first and then to JSON with json.dumps().

Example without the Discovery API using MessageToDict() :

import json
from google.cloud import vision
from google.cloud.vision import types
from google.protobuf.json_format import MessageToDict

class GoogleVision():

    def detectLabels(self, uri):

        # Instantiates a client
        client = vision.ImageAnnotatorClient()

        # Image file
        file_name=uri

        # Loads the image into memory
        with open(file_name, 'rb') as image:
            image_content = image.read()

        image = types.Image(content=image_content)

        # Performs label detection on the image file
        response = client.label_detection(image=image)       

        #Convert the response to dictionary
        response = MessageToDict(response)

        # Convert to Json
        res_json = json.dumps(response)

        return res_json
Livvyy answered 8/10, 2018 at 15:45 Comment(1)
Using a two-step MessageToDict followed by conversion to JSON is an excellent suggestion; for me, it works better than MessageToJson when applied to Google's Vision API responses, because (at least in my hands) applying MessageToJson to the API's Protocol Buffer responses produces a string.Said
L
0

You can try:

from google.protobuf.json_format import MessageToDict


(Pdb) type(response)
<class 'google.cloud.vision_v1.types.image_annotator.BatchAnnotateFilesResponse'>

print(MessageToDict(response._pb))
{'responses': [{'responses': [...]},...]}
Lola answered 18/7 at 21:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.