在GAE中使用boto和gcs_oauth2_boto_plugin通过服务账号访问Cloud Storage
我想知道有没有人知道怎么用服务账号来认证,以便我可以通过以下方式访问云存储的数据:
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 个回答
这个回答没有直接解决问题,但我想说的是,我没有使用boto和gcs_oauth2_boto_plugin,而是用了“Google Cloud Storage Python Client Library”,也就是从pip安装的GoogleAppEngineCloudStorageClient
。
https://developers.google.com/appengine/docs/python/googlecloudstorageclient/