我想构建一个可以轻松与Google存储设备交互的应用程序,即在存储桶中列出文件,下载文件并上传文件。
在学习完本教程之后,我决定使用服务帐户(而不是用户帐户)进行身份验证,并按照此过程进行操作。我在控制台上创建了公用/专用密钥,然后在计算机上下载了密钥。然后,我创建了指向该私钥的.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文件(该文件指向我的服务帐户私钥)吗?还是有一种更清洁/更简便的方法来允许我的应用程序访问Google存储空间以进行输入/输出交互?
例如,当我想使用连接到S3存储桶时,只需要向程序提供公共和私有密钥作为字符串即可boto
。我不需要生成.boto文件,导入包等...,这使它使用起来非常容易,不是吗?
1-您如何解释删除代码中未使用的导入会导致导入失败?
第一个提示是该模块被命名为“插件”,尽管表面上尚不清楚确切的实现方式。从直觉上讲,虽然不导入模块会导致此类异常,这在某种意义上是有道理的。起初,我以为是在做一个全球性的活动状态的不良做法的init导入一个模块。在某些方面,这就是原来的样子,但这仅仅是因为类层次结构在元可编程python中是“状态”。
事实证明(在许多情况下)检查从(boto.auth.get_auth_handler()
)抛出stacktrace的位置是理解该问题的关键。
(请参阅链接的源以获取注释版本)
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)))
注意对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
因此,很明显,终于终于看到了中的类的类定义,该类OAuth2Auth
中的类定义gcs_oauth2_boto_plugin.oauth2_plugin
被声明为的子类boto.auth_handler.AuthHandler
,并通过以下成员变量将其身份验证功能传递给boto框架:
capability = ['google-oauth2', 's3']
2-更一般而言,要确保了解身份验证过程,如果要在计算机上运行应用程序,必须确保事先生成.boto文件(该文件指向我的服务帐户私钥)吗?还是有一种更清洁/更简便的方法来允许我的应用程序访问Google存储空间以进行输入/输出交互?
这是一个更笼统的答案:您可以使用.boto文件,尽管您也可以使用服务帐户凭据,甚至可以使用REST API并通过oauth2流获取在Authorization标头中发送所需的令牌。文档中提供了多种对云存储进行身份验证的方法。您链接的教程/文档显示了一些方法,您使用.boto作为另一种方法。您可以在此处阅读有关Cloud Storage REST API(JSON)的信息,并在此处阅读有关各种python oauth2流的信息。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句