I've followed the instructions the Google Client Libraries page for the Vision API to get started with the Vision API in Python (I'm running 2.7). Since my code is running in Docker (a Flask app), I've followed the instructions in the following way:
The steps above result in the error below:
> RetryError: GaxError(Exception occurred in retry method that was not
> classified as transient, caused by <_Rendezvous of RPC that terminated
> with (StatusCode.UNAUTHENTICATED, Traceback (most recent call last):
> File "src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi",
> line 154, in grpc._cython.cygrpc.plugin_get_metadata
> (src/python/grpcio/grpc/_cython/cygrpc.c:7054) File
> "/usr/local/lib/python2.7/site-packages/grpc/_plugin_wrapping.py",
> line 106, in __call__
> AuthMetadataPluginCallback(wrapped_cygrpc_callback)) File "/usr/local/lib/python2.7/site-packages/google/auth/transport/grpc.py",
> line 73, in __call__
> callback(self._get_authorization_headers(context), None) File "/usr/local/lib/python2.7/site-packages/google/auth/transport/grpc.py",
> line 61, in _get_authorization_headers
> headers) File "/usr/local/lib/python2.7/site-packages/google/auth/credentials.py",
> line 121, in before_request
> self.refresh(request) File "/usr/local/lib/python2.7/site-packages/google/oauth2/service_account.py",
> line 310, in refresh
> request, self._token_uri, assertion) File "/usr/local/lib/python2.7/site-packages/google/oauth2/_client.py",
> line 143, in jwt_grant
> response_data = _token_endpoint_request(request, token_uri, body) File
> "/usr/local/lib/python2.7/site-packages/google/oauth2/_client.py",
> line 98, in _token_endpoint_request
> body = urllib.parse.urlencode(body) AttributeError: 'Module_six_moves_urllib_parse' object has no attribute 'urlencode'
> )>)
I'm thinking the problem has to do with my crendtials since it says StatusCode.UNAUTHENTICATED, but I haven't been able to get this fixed. Could anyone help? Thanks!
TL;DR - You're having issues with the Credentials as you've already observed. Using Application Default Credentials will be much simpler and will make your application portable across multiple environments. More specifically, if you already have a working set of credentials in gcloud
, you can do a one-time step to activate Application Default Credentials in gcloud
using gcloud auth application-default login
.
Greg, I tried the example on my machine, following the steps mentioned on the Cloud Vision API Client libraries page and it works for me.
In case, if the steps were not clear, I'll walk you over:
Install the google-cloud-vision
python package. (From your post you seem to have done this already).
pip install --upgrade google-cloud-vision
Set up Application Default Credentials on your machine / docker container. You seemed to mention that you ran gcloud init
successfully. This is not sufficient to set up Application Default Credentials. Instead, you will have to run the following command mentioned in the steps which will ask you to open a link in the browser and you will have to paste back the confirmation from the browser back into your command line.
gcloud auth application-default login
Download the test image wakeupcat.jpg
or use an image of your own. This part unfortunately is not clearly mentioned on the page.
Create a file named cloud-vision-example.py
or any other name you prefer with the following content (NOTE: I've updated the image file path here):
cloud-vision-example.py
import io
import os
# Imports the Google Cloud client library
from google.cloud import vision
# Instantiates a client
vision_client = vision.Client()
# The name of the image file to annotate
file_name = os.path.join('.', 'wakeupcat.jpg')
# Loads the image into memory
with io.open(file_name, 'rb') as image_file:
content = image_file.read()
image = vision_client.image(
content=content)
# Performs label detection on the image file
labels = image.detect_labels()
print('Labels:')
for label in labels:
print(label.description)
python cloud-vision-example.py
.Output:
$ python cloud-vision-example.py
Labels:
cat
photo caption
small to medium sized cats
cat like mammal
whiskers
snout
kitten
asian
If you would like to use the credentials from a service account, you can create a new service account, download the private key json file and point the environment variable GOOGLE_APPLICATION_CREDENTIALS
at the json file (it looks like you did, but you might want to double check if you downloaded the right credentials and the path is valid).
If GOOGLE_APPLICATION_CREDENTIALS
is not set, the client library will try to use the gcloud application default credentials (which should have been setup prior to this).
If your app is running on App Engine or Compute Engine, the associated built-in service account will be used as the last resort.