使用Python验证Google存储空间

时间:2015-11-03 06:17:36

标签: python google-oauth google-cloud-storage boto

我想构建一个与谷歌存储轻松互动的应用程序,即存储桶中的列表文件,下载文件和上传文件。

this tutorial之后,我决定使用服务帐户(而不是用户帐户)进行身份验证,然后按照以下步骤操作。我在控制台上创建了一个公钥/私钥,并在我的机器上下载了密钥。然后我创建了指向这个私钥的.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文件(指向我的服务帐户私钥) ?或者是否有一种更清晰/更简单的方式来访问我的应用程序到谷歌存储进行进/出交互?

例如,当我想连接到boto的S3存储桶时,我只需要将公钥和私钥作为字符串提供给我的程序。我不需要生成.boto文件,导入包等......这使得它更容易使用,不是吗?

1 个答案:

答案 0 :(得分:1)

  

1-如何解释删除代码中未使用的导入会导致失败?

第一个提示是该模块被命名为&#34;插件&#34;,尽管表面上的实现方式并不清晰。直观地说,不导入模块会导致这种异常。最初,我认为在导入该模块的 init 期间对全局进行有状态活动是一种不好的做法。在某些方面,就是这样,但只是因为类层次结构是&#34; state&#34;在元可编程python中。

事实证明(在许多情况下)检查堆栈跟踪从(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)))

请注意对类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

因此,当我们在gcs_oauth2_boto_plugin.oauth2_plugin中看到类OAuth2Auth的类定义时,它终于变得清晰了,其中它被声明为boto.auth_handler.AuthHandler的子类,信令通过以下成员变量对boto框架的auth功能:

capability = ['google-oauth2', 's3']
  

2-更一般地说,为了确保了解身份验证过程,如果我想在计算机上运行我的应用程序,我必须确保先前生成的.boto文件(指向我的服务帐户私钥) ?或者是否有一种更清晰/更简单的方式来访问我的应用程序到谷歌存储进行进/出交互?

这有一个更通用的答案:你可以使用.boto文件,虽然你也可以使用服务帐户凭据,你甚至可以使用REST API并通过oauth2流来获取发送所需的令牌。授权标头。 auth到云存储的各种方法都在文档中。您链接的教程/ doc显示了一些方法,您已将.boto用于另一种方法。您可以阅读有关Cloud Storage REST API(JSON)here的内容,您可以阅读各种类型的{python oauth2流here