StatusCode.UNAUTHENTICATED when 运行 Vision API demo in Python/Flask 运行 in Docker

StatusCode.UNAUTHENTICATED when running Vision API demo in Python/Flask running in Docker

我已经按照 Google Client Libraries page 的 Vision API 说明开始使用 Python 中的 Vision API(我是 运行宁 2.7)。由于我的代码是 运行ning 在 Docker(一个 Flask 应用程序)中,我按照以下方式按照说明进行操作:

  1. 在我的 requirements.txt 文件中添加了 google-cloud-vision 和 google-cloud 库。
  2. 创建了一个 json 帐户凭据文件并将此文件的位置设置为名为 GOOGLE_APPLICATION_CREDENTIALS
  3. 的环境变量
  4. 运行 gcloud 初始化成功,同时 "ssh'd" 进入我的网络应用程序的 docker 容器
  5. 将上面 link 中的客户端库示例完全复制到测试视图中 运行 代码

上述步骤导致以下错误:

> 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'
> )>)

我认为问题与我的凭据有关,因为它显示 StatusCode.UNAUTHENTICATED,但我无法解决此问题。有人能帮忙吗?谢谢!

TL;DR - 正如您已经观察到的那样,您遇到了凭据问题。使用 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,我按照 Cloud Vision API Client libraries 页面上提到的步骤在我的机器上试过这个例子,它对我有用。

如果步骤不清楚,我会带你过去:

  1. 安装 google-cloud-vision python 软件包。 (从您的 post 来看,您似乎已经这样做了)。

    pip install --upgrade google-cloud-vision

  2. 在您的计算机/docker 容器上设置应用程序默认凭据。您似乎提到您 运行 gcloud init 成功了。这不足以设置应用程序默认凭据。相反,您将必须 运行 步骤中提到的以下命令,这将要求您在浏览器中打开 link 并且您必须将浏览器的确认粘贴回命令行.

    gcloud auth application-default login

  3. 下载 test image wakeupcat.jpg 或使用您自己的图片。不幸的是,这部分没有在页面上明确提及。

  4. 创建一个名为 cloud-vision-example.py 或您喜欢的任何其他名称的文件,内容如下(注意:我已在此处更新了图像文件路径):

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)
  1. 运行 python 脚本。 python cloud-vision-example.py.

输出:

$ python cloud-vision-example.py
Labels:
cat
photo caption
small to medium sized cats
cat like mammal
whiskers
snout
kitten
asian

How Application Default Credentials work

  • 如果您想使用服务帐户的凭证,您可以create a new service account,下载私钥json文件并指向环境变量GOOGLE_APPLICATION_CREDENTIALS 在 json 文件中(看起来像你这样做了,但你可能需要仔细检查你是否下载了正确的凭据并且路径是否有效)。

  • 如果未设置 GOOGLE_APPLICATION_CREDENTIALS,客户端库将尝试使用 gcloud 应用程序默认凭据(应该在此之前设置)。

  • 如果您的应用运行正在 App Engine 或 Compute Engine 上运行,关联的内置服务帐户将作为最后的手段使用。