在Google Apps Engine python项目中使用Google Drive API和服务帐户,并进行本地调试

vic*_*ans 7 google-app-engine oauth-2.0 google-drive-api

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

我的设置:

  • Eclipse 4.4
  • 适用于Python 1.8.0的Google App Engine SDK
  • Google API客户端Python GAE 1.1

我在app.yaml中激活(以及其他)这些第三方库:

- name: pycrypto
  version: latest
- name: ssl
  version: latest
Run Code Online (Sandbox Code Playgroud)

这是我对设置软件的理解,在几个陈述中:

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

我真的想要本地调试工具,因为我正在学习python并学习google驱动器接口,因此在服务器上进行调试是一个很大的负担.

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

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

=>我要解释的第一个问题是:是否可以在GAE SDK中使用Python在本地系统上对Google Drive API进行身份验证?也许答案很简单'不'?

=>如果答案是'是',那么是否会有一个示例设置和代码示例,以显示实现此本地身份验证的方式?

=>错误日志(下面)似乎表明pycrypto仍然存在问题,但是文档明确地说它包含在Python 2.7 GAE运行时环境中.

=>也许(请确认)我对本地和服务器python设置之间的区别感到困惑.当我在Eclipse中查看'Run Local'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)
Run Code Online (Sandbox Code Playgroud)

这是我的错误日志:

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.
Run Code Online (Sandbox Code Playgroud)

[更新]回顾我的问题,我想我需要仔细研究一下本地安装pycrypto.如果这是修复,我将对本文提供反馈,要求添加关于GAE服务器运行时库与本地SDK库之间的差异的注释.我也会在这里添加安装说明.

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

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

小智 1

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

关于旧的和新的 dev_server 中的导入问题,我无法写任何内容,因为我对此一无所知。