在GAE中使用boto和gcs_oauth2_boto_plugin通过服务账号访问Cloud Storage

1 投票
1 回答
923 浏览
提问于 2025-04-18 18:38

我想知道有没有人知道怎么用服务账号来认证,以便我可以通过以下方式访问云存储的数据:
1. 使用boto库(和gcs_oauth2_boto_plugin)
2. 在Google App Engine(GAE)上运行

根据这个链接 https://developers.google.com/storage/docs/gspythonlibrary,我正在使用boto和gcs_oauth2_boto_plugin来进行认证,并对云存储执行操作(上传/下载文件)。我使用服务账号进行认证,这样我们就不需要定期用Google账号进行认证(因为如果我们在GCE上运行,这个代码会用GCE的服务账号来运行——不过我还没实际尝试过)。在本地,我已经设置了boto的配置文件,使用服务账号并指向一个p12密钥文件。这在本地运行得很好。

我想用相同的代码从Google App Engine(GAE)与云存储进行交互。我们正在运行一个轻量级的ETL过程,将数据转换并加载到Big Query中。我们希望在App Engine的任务队列中运行这段代码(这个任务是由云存储的对象变更通知触发的)。

由于我们目前依赖于boto配置文件(~/.boto),我参考了这个链接 http://thurloat.com/2010/06/07/google-storage-and-app-engine,将服务账号的相关配置项添加进去。

当我最终从App Engine(dev_appserver.py)运行代码时,出现了下面的错误信息:

Traceback (most recent call last):
  File "/home/some-user/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1536, in __call__
    rv = self.handle_exception(request, response, e)
  File "/home/some-user/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "/home/some-user/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/home/some-user/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/home/some-user/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/home/some-user/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/home/some-user/dev/myApp/main.py", line 247, in post
    gs.download(fname, fp)
  File "/home/some-user/dev/myApp/cloudstorage.py", line 107, in download
    bytes = src_uri.get_key().get_contents_to_file(fp)
  File "/home/some-user/dev/myApp/boto/storage_uri.py", line 336, in get_key
    bucket = self.get_bucket(validate, headers)
  File "/home/some-user/dev/myApp/boto/storage_uri.py", line 181, in get_bucket
    conn = self.connect()
  File "/home/some-user/dev/myApp/boto/storage_uri.py", line 140, in connect
    **connection_args)
  File "/home/some-user/dev/myApp/boto/gs/connection.py", line 47, in __init__
    suppress_consec_slashes=suppress_consec_slashes)
  File "/home/some-user/dev/myApp/boto/s3/connection.py", line 190, in __init__
    validate_certs=validate_certs, profile_name=profile_name)
  File "/home/some-user/dev/myApp/boto/connection.py", line 568, in __init__
    host, config, self.provider, self._required_auth_capability())
  File "/home/some-user/dev/myApp/boto/auth.py", line 929, in get_auth_handler
    ready_handlers.append(handler(host, config, provider))
  File "/home/some-user/dev/myApp/gcs_oauth2_boto_plugin/oauth2_plugin.py", line 56, in __init__
    cred_type=oauth2_client.CredTypes.OAUTH2_SERVICE_ACCOUNT)
  File "/home/some-user/dev/myApp/gcs_oauth2_boto_plugin/oauth2_helper.py", line 48, in OAuth2ClientFromBotoConfig
    token_cache = oauth2_client.FileSystemTokenCache()
  File "/home/some-user/dev/myApp/gcs_oauth2_boto_plugin/oauth2_client.py", line 175, in __init__
    tempfile.gettempdir(), 'oauth2_client-tokencache.%(uid)s.%(key)s')
  File "/home/some-user/google-cloud-sdk/platform/google_appengine/google/appengine/dist/tempfile.py", line 61, in PlaceHolder
    raise NotImplementedError("Only tempfile.TemporaryFile is available for use")
NotImplementedError: Only tempfile.TemporaryFile is available for use

看起来问题出在gcs_oauth2_boto_plugin试图在缓存oauth凭证时使用临时目录(App Engine只支持tempfile.TemporaryFile)。

与其尝试修补gcs_oauth2_boto_plugin,是否还有其他解决方案?我们能否在App Engine上使用服务账号与gcs_oauth2_boto_plugin/boto一起访问云存储资源?

或者,我是不是在这里使用了错误的认证方法?

1 个回答

0

这个回答没有直接解决问题,但我想说的是,我没有使用boto和gcs_oauth2_boto_plugin,而是用了“Google Cloud Storage Python Client Library”,也就是从pip安装的GoogleAppEngineCloudStorageClient

https://developers.google.com/appengine/docs/python/googlecloudstorageclient/

撰写回答