7

在过去的几天里(在我可以花在这个项目上的奇怪时间里),我一直在努力开始使用 Google Drive API 和 GAE python 中的服务帐户进行本地调试。

我的设置:

  • 日食 4.4
  • 适用于 Python 1.8.0 的 Google App Engine SDK
  • 谷歌 API 客户端 Python GAE 1.1

我已经在 app.yaml 中激活了(除其他外)这些 3rd 方库:

- name: pycrypto
  version: latest
- name: ssl
  version: latest

到目前为止,这是我对设置的理解,有几个陈述:

  • 因为我的应用不需要访问用户文件,而是特定于应用的文件,所以应用应该使用“服务帐户”来拥有和访问 Google Drive 上的文件
  • 服务帐户可以通过两种方式进行身份验证:(1) 通过 API 密钥和 (2) 通过私钥凭证
  • 使用 SDK 开发 GAE 应用程序时,需要考虑两个环境:本地系统(用于调试)和 GAE 服务器(用于部署)
  • 在本地系统上运行时,API 密钥身份验证不起作用(并且永远不会起作用),因为是两条腿的身份验证(不要完全掌握这个......,但它似乎是真的)

很想要本地调试工具,因为我是学python,学google驱动接口,所以在服务器上调试是个很大的负担。

所以我需要让私钥凭证在本地系统上工作。但后来我遇到了问题“ImportError:无法导入名称 SignedJwtAssertionCredentials”。尝试了我在网上找到的几乎所有东西:

  • 使用 python 2.7 运行时并启用 pycrypto 库
  • 将 google-api-python-client-gae 升级到 1.1(包括此修复)
  • 在我的系统上安装了 OpenSSL(但可能没有成功设置正确的路径)
  • 阅读说明以在本地安装 pycrypto,但假设它们已过时

=>我的第一个问题,只是为了理解,是:是否有可能在本地系统上使用 Python 从 GAE SDK 到 Google Drive API 进行身份验证?也许答案很简单“不”?

=> 如果答案是“是”,那么是否会有示例设置和代码示例来展示实现此本地身份验证的方法?

=> 错误日志(如下)似乎表明 pycrypto 不可用仍然存在问题,但文档非常明确地说它包含在 Python 2.7 GAE 运行时环境中。

=>也许(请确认)我对本地和服务器python设置之间的区别感到困惑。当我在 Eclipse 中查看“运行本地”PYTHONPATH 时,它包括(1)我的项目文件夹,(2)google-api-client-python-gae 文件夹(似乎不包括 pycrypto !!),而GAE 运行时 --- 有什么区别?(3) 我的本地 Python 2.7 部署。那么这个本地配置中缺少什么我需要模仿服务器配置才能开始调试?

这是我使用私钥凭据进行身份验证的代码:

from oauth2client.client import SignedJwtAssertionCredentials
f = file(SERVICE_ACCOUNT_PKCS12_FILE_PATH, 'rb')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials(SERVICE_ACCOUNT_EMAIL, key, scope=OAUTH_SCOPE)
http = httplib2.Http()
http = credentials.authorize(http)
return build('drive', 'v2', http=http)

这是我的错误日志:

ERROR    2013-06-18 00:59:57,562 dev_appserver_import_hook.py:1251] Third party package Crypto was enabled in app.yaml but not found on import. You may have to download and install it.
ERROR    2013-06-18 00:59:59,255 dev_appserver_import_hook.py:1251] Third party package Crypto was enabled in app.yaml but not found on import. You may have to download and install it.
ERROR    2013-06-18 00:59:59,289 webapp2.py:1552] import_string() failed for 'illustrations.SyncHandler'. Possible reasons are:

- missing __init__.py in a package;
- package or module path not included in sys.path;
- duplicated package or module name taking precedence in sys.path;
- missing module, class, function or variable;

Original exception:

ImportError: cannot import name SignedJwtAssertionCredentials

Debugged import:

- 'illustrations' not found.
Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1272, in default_dispatcher
    self.handlers[handler] = handler = import_string(handler)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1850, in import_string
    return getattr(__import__(module, None, None, [obj]), obj)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 692, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 1766, in load_module
    return self.FindAndLoadModule(submodule, fullname, search_path)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 692, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 1630, in FindAndLoadModule
    description)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 692, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 1577, in LoadModuleRestricted
    description)
  File "C:\Users\vic\Dropbox\Development\Eclipse-juno-workspace\Missale\src\illustrations.py", line 6, in <module>
    import drive
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 692, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 1766, in load_module
    return self.FindAndLoadModule(submodule, fullname, search_path)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 692, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 1630, in FindAndLoadModule
    description)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 692, in Decorate
    return func(self, *args, **kwargs)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 1577, in LoadModuleRestricted
    description)
  File "C:\Users\vic\Dropbox\Development\Eclipse-juno-workspace\Missale\src\drive.py", line 6, in <module>
    from oauth2client.client import SignedJwtAssertionCredentials
ImportStringError: import_string() failed for 'illustrations.SyncHandler'. Possible reasons are:

- missing __init__.py in a package;
- package or module path not included in sys.path;
- duplicated package or module name taking precedence in sys.path;
- missing module, class, function or variable;

Original exception:

ImportError: cannot import name SignedJwtAssertionCredentials

Debugged import:

- 'illustrations' not found.

[更新] 回顾我的问题,我想我需要仔细研究在本地安装 pycrypto。如果这是解决方法,我将就这篇文章提供反馈中提供反馈,以请求添加有关 GAE 服务器运行时库和本地 SDK 库之间差异的注释。我也会在这里添加安装说明。

[update2] SignedJwtAssertionCredentials 导入问题已经解决,但是 tlslite 包上出现了另一个导入问题。我不知道如何解决这个问题,因为导入看起来非常正常,我求助于从头开始重新配置整个 IDE。我现在安装了另一个预编译的 pycrypto 库,并按照错误消息中的提示,将我的 .p12 私钥文件转换为 .pem 文件。请注意,openssl 创建的 .pem 文件在“-----BEGIN”之前包含 4 个文本行,我必须手动删除这些文本行才能使 .pem 文件被 oauth2client 识别!

[update3] 从头开始​​重新配置 IDE 时,我忽略了使用“old_dev_appserver.py”在本地运行应用程序,而不是“dev_appserver.py”。后者不会启用断点!但它看起来与 SignedJwtAssertionCredentials 导入问题有关。使用“dev_appserver.py”,我没有导入问题(但没有断点),使用“old_dev_appserver.py”,我可以重现导入问题。所以'old_dev_appserver.py'可能一直是问题的一部分!

4

1 回答 1

1

是的 - 您可以使用 SignedJwtAssertionCredentials 连接到 Google 服务。我编写了一次执行此操作的代码,并且效果很好。使用该类是一个问题。在 GAE 上提供了您编写的 PyCrypto 库,但在本地您必须手动安装它。GAE 有他自己的这个库的修改版本,所以他们没有提供她的源代码。该库的第二个问题是她是为将使用她的指定机器编译的。如果您查看该类的源代码,您会发现她需要一些依赖项才能工作。如果他们不符合该课程的要求,她将无法从外部代码访问。

关于在新旧 dev_server 中导入的问题我什么也写不出来,因为我对此一无所知。

于 2014-01-07T21:42:15.853 回答