使用 Python 对 Google 存储进行身份验证
authentification for Google Storage using Python
我想构建一个可以与 google 存储轻松交互的应用程序,即列出存储桶中的文件、下载文件和上传文件。
在 this tutorial 之后,我决定使用服务帐户(而不是用户帐户)进行身份验证并遵循该过程。我在我的控制台上创建了一个 public/private 密钥,并在我的机器上下载了该密钥。然后我创建了指向这个私钥的 .boto 文件,最后启动了这个程序并且它成功了:
import boto
import gcs_oauth2_boto_plugin
uri = boto.storage_uri('txxxxxxxxxxxxxx9.appspot.com', 'gs')
for obj in uri.get_bucket():
print '%s://%s/%s' % (uri.scheme, uri.bucket_name, obj.name)
如您所见,代码中未使用包 gcs_oauth2_boto_plugin
,所以我决定去掉它。但神奇的是,当我再次评论 import gcs_oauth2_boto_plugin
行和 运行 程序时,我得到了这个错误:
C:\Users\...\Anaconda3\envs\snakes\python.exe C:/Users/.../Dropbox/Prog/s3_manifest_builder/test.py
Traceback (most recent call last):
File "C:/Users/.../Dropbox/Prog/s3_manifest_builder/test.py", line 10, in <module>
for obj in uri.get_bucket():
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\storage_uri.py", line 181, in get_bucket
conn = self.connect()
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\storage_uri.py", line 140, in connect
**connection_args)
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\gs\connection.py", line 47, in __init__
suppress_consec_slashes=suppress_consec_slashes)
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\s3\connection.py", line 190, in __init__
validate_certs=validate_certs, profile_name=profile_name)
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\connection.py", line 569, in __init__
host, config, self.provider, self._required_auth_capability())
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\auth.py", line 987, in get_auth_handler
'Check your credentials' % (len(names), str(names)))
boto.exception.NoAuthHandlerFound: No handler was ready to authenticate. 1 handlers were checked. ['HmacAuthV1Handler'] Check your credentials
所以我的问题是:
1- 你如何解释删除代码中未使用的导入会导致失败?
2- 更一般地说,为了确保了解身份验证过程,如果我想 运行 我的应用程序在机器上,我必须确保有 .boto 文件(它指向我的服务帐户私钥)之前生成的?或者是否有一种 cleaner/easier 方法可以让我的应用程序访问 Google 存储以进行 in/out 交互?
例如,当我想使用 boto
连接到 S3 存储桶时,我只需向我的程序提供 public 和私钥作为字符串。我不需要生成 .boto 文件、导入包等...,这使得它更易于使用,不是吗?
1- how can you explain that deleting an import which IS NOT USED in the code makes it fail?
第一个提示是该模块被命名为 "plugin",尽管表面上并不清楚具体是如何实现的。不过,从直觉上讲,不导入模块会导致此类异常。最初,我认为在导入该模块的 init 期间对全局执行有状态 activity 是一种不好的做法。在某些方面,它就是这样,但这只是因为 class 层次结构在 meta-programmable python 中是 "state"。
事实证明(在许多情况下)检查堆栈跟踪的抛出位置 (boto.auth.get_auth_handler()
) 提供了理解问题的关键。
(请参阅评论版本的链接源)
def get_auth_handler(host, config, provider, requested_capability=None):
ready_handlers = []
auth_handlers = boto.plugin.get_plugin(AuthHandler, requested_capability)
for handler in auth_handlers:
try:
ready_handlers.append(handler(host, config, provider))
except boto.auth_handler.NotReadyToAuthenticate:
pass
if not ready_handlers:
checked_handlers = auth_handlers
names = [handler.__name__ for handler in checked_handlers]
raise boto.exception.NoAuthHandlerFound(
'No handler was ready to authenticate. %d handlers were checked.'
' %s '
'Check your credentials' % (len(names), str(names)))
注意对 class AuthHandler 的引用,它在 boto.auth_handler
中定义。
所以,可以看出我们需要看boto.plugin.get_plugin(AuthHandler, requested_capability)
的内容:
def get_plugin(cls, requested_capability=None):
if not requested_capability:
requested_capability = []
result = []
for handler in cls.__subclasses__():
if handler.is_capable(requested_capability):
result.append(handler)
return result
所以,终于清楚了,最后当我们看到 class OAuth2Auth
在 gcs_oauth2_boto_plugin.oauth2_plugin
中的 class 定义时,它被声明为boto.auth_handler.AuthHandler
的子class,通过以下成员变量向 boto 框架发送其身份验证功能:
capability = ['google-oauth2', 's3']
2- more generally, to be sure to understand the authentification process, if I want to run my app on a machine, I must be sure to have the .boto file (which points to my service account private key) generated previously? Or is there a cleaner/easier way to give access to my application to Google Storage for in/out interactions?
这有一个更通用的答案:您可以使用 .boto 文件,尽管您也可以使用服务帐户凭据,甚至可以使用 REST API 并通过 oauth2 流程获取发送授权所需的令牌 header。云存储授权的各种方法在文档中。您链接的 tutorial/doc 显示了一些方法,您已将 .boto 用于另一种方法。您可以阅读有关 Cloud Storage REST API (JSON) here and you can read about python oauth2 flows of various kinds here 的信息。
我想构建一个可以与 google 存储轻松交互的应用程序,即列出存储桶中的文件、下载文件和上传文件。
在 this tutorial 之后,我决定使用服务帐户(而不是用户帐户)进行身份验证并遵循该过程。我在我的控制台上创建了一个 public/private 密钥,并在我的机器上下载了该密钥。然后我创建了指向这个私钥的 .boto 文件,最后启动了这个程序并且它成功了:
import boto
import gcs_oauth2_boto_plugin
uri = boto.storage_uri('txxxxxxxxxxxxxx9.appspot.com', 'gs')
for obj in uri.get_bucket():
print '%s://%s/%s' % (uri.scheme, uri.bucket_name, obj.name)
如您所见,代码中未使用包 gcs_oauth2_boto_plugin
,所以我决定去掉它。但神奇的是,当我再次评论 import gcs_oauth2_boto_plugin
行和 运行 程序时,我得到了这个错误:
C:\Users\...\Anaconda3\envs\snakes\python.exe C:/Users/.../Dropbox/Prog/s3_manifest_builder/test.py
Traceback (most recent call last):
File "C:/Users/.../Dropbox/Prog/s3_manifest_builder/test.py", line 10, in <module>
for obj in uri.get_bucket():
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\storage_uri.py", line 181, in get_bucket
conn = self.connect()
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\storage_uri.py", line 140, in connect
**connection_args)
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\gs\connection.py", line 47, in __init__
suppress_consec_slashes=suppress_consec_slashes)
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\s3\connection.py", line 190, in __init__
validate_certs=validate_certs, profile_name=profile_name)
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\connection.py", line 569, in __init__
host, config, self.provider, self._required_auth_capability())
File "C:\Users\...\Anaconda3\envs\snakes\lib\site-packages\boto\auth.py", line 987, in get_auth_handler
'Check your credentials' % (len(names), str(names)))
boto.exception.NoAuthHandlerFound: No handler was ready to authenticate. 1 handlers were checked. ['HmacAuthV1Handler'] Check your credentials
所以我的问题是:
1- 你如何解释删除代码中未使用的导入会导致失败?
2- 更一般地说,为了确保了解身份验证过程,如果我想 运行 我的应用程序在机器上,我必须确保有 .boto 文件(它指向我的服务帐户私钥)之前生成的?或者是否有一种 cleaner/easier 方法可以让我的应用程序访问 Google 存储以进行 in/out 交互?
例如,当我想使用 boto
连接到 S3 存储桶时,我只需向我的程序提供 public 和私钥作为字符串。我不需要生成 .boto 文件、导入包等...,这使得它更易于使用,不是吗?
1- how can you explain that deleting an import which IS NOT USED in the code makes it fail?
第一个提示是该模块被命名为 "plugin",尽管表面上并不清楚具体是如何实现的。不过,从直觉上讲,不导入模块会导致此类异常。最初,我认为在导入该模块的 init 期间对全局执行有状态 activity 是一种不好的做法。在某些方面,它就是这样,但这只是因为 class 层次结构在 meta-programmable python 中是 "state"。
事实证明(在许多情况下)检查堆栈跟踪的抛出位置 (boto.auth.get_auth_handler()
) 提供了理解问题的关键。
(请参阅评论版本的链接源)
def get_auth_handler(host, config, provider, requested_capability=None):
ready_handlers = []
auth_handlers = boto.plugin.get_plugin(AuthHandler, requested_capability)
for handler in auth_handlers:
try:
ready_handlers.append(handler(host, config, provider))
except boto.auth_handler.NotReadyToAuthenticate:
pass
if not ready_handlers:
checked_handlers = auth_handlers
names = [handler.__name__ for handler in checked_handlers]
raise boto.exception.NoAuthHandlerFound(
'No handler was ready to authenticate. %d handlers were checked.'
' %s '
'Check your credentials' % (len(names), str(names)))
注意对 class AuthHandler 的引用,它在 boto.auth_handler
中定义。
所以,可以看出我们需要看boto.plugin.get_plugin(AuthHandler, requested_capability)
的内容:
def get_plugin(cls, requested_capability=None):
if not requested_capability:
requested_capability = []
result = []
for handler in cls.__subclasses__():
if handler.is_capable(requested_capability):
result.append(handler)
return result
所以,终于清楚了,最后当我们看到 class OAuth2Auth
在 gcs_oauth2_boto_plugin.oauth2_plugin
中的 class 定义时,它被声明为boto.auth_handler.AuthHandler
的子class,通过以下成员变量向 boto 框架发送其身份验证功能:
capability = ['google-oauth2', 's3']
2- more generally, to be sure to understand the authentification process, if I want to run my app on a machine, I must be sure to have the .boto file (which points to my service account private key) generated previously? Or is there a cleaner/easier way to give access to my application to Google Storage for in/out interactions?
这有一个更通用的答案:您可以使用 .boto 文件,尽管您也可以使用服务帐户凭据,甚至可以使用 REST API 并通过 oauth2 流程获取发送授权所需的令牌 header。云存储授权的各种方法在文档中。您链接的 tutorial/doc 显示了一些方法,您已将 .boto 用于另一种方法。您可以阅读有关 Cloud Storage REST API (JSON) here and you can read about python oauth2 flows of various kinds here 的信息。