ここ数日間 (このプロジェクトに費やすことができる奇数時間)、ローカル デバッグのために、GAE python のサービス アカウントで Google ドライブ API を使い始めるのに苦労していました。
私のセットアップ:
- エクリプス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
これは、いくつかのステートメントで、セットアップソファについて理解していることです。
- 私のアプリはユーザー ファイルにアクセスする必要はありませんが、アプリ固有のファイルにアクセスする必要があるため、アプリは「サービス アカウント」を使用して Google ドライブ上のファイルを所有し、アクセスする必要があります。
- サービス アカウントは、(1) API キーによる認証と (2) 秘密鍵の資格情報の 2 つの方法で認証できます。
- SDK を使用して GAE アプリを開発する場合は、ローカル システム (デバッグ用) と GAE サーバー (デプロイ用) の 2 つの環境を考慮する必要があります。
- APIキー認証は、ローカルシステムで実行すると機能しません(そして機能することはありません)。これは、二足認証のためです(これを完全に把握していません...しかし、本当のようです)
ローカルのデバッグ機能がどうしても欲しいのですが、pythonを勉強していてgoogleドライブのインターフェースを学んでいるので、サーバー上でのデバッグは大変な負担です。
そのため、ローカル システムで機能する秘密鍵の資格情報を取得する必要があります。しかし、その後、「ImportError: 名前 SignedJwtAssertionCredentials をインポートできません」という問題に遭遇します。Webで見つけたほとんどすべてを試しました:
- Python 2.7 ランタイムを使用し、pycrypto ライブラリを有効にします
- google-api-python-client-gae を 1.1 にアップグレードする (これにはこの修正が含まれます)
- システムに OpenSSL をインストールしました (ただし、正しいパスの設定に失敗した可能性があります)。
- pycrypto をローカルにインストールする手順を読んでください。
=> 私の最初の質問は、理解するために、Python を使用して GAE SDK 内から Google ドライブ 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)
これは私のエラーログです:
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 ライブラリの間の不一致に関するメモを追加するよう依頼します。また、インストール手順もここに追加します。
[更新 2] SignedJwtAssertionCredentials のインポートの問題はなくなりましたが、tlslite パッケージで別のインポートの問題が発生しました。インポートが完全に正常に見えたので、これを修正する方法がわかりませんでした。そして、IDE 全体を最初から再構成することにしました。別のプリコンパイル済み pycrypto ライブラリをインストールし、エラー メッセージのヒントに従い、.p12 秘密鍵ファイルを .pem ファイルに変換しました。openssl によって作成された .pem ファイルには、「-----BEGIN」の前に 4 つのテキスト行が含まれていることに注意してください。.pem ファイルが oauth2client によって認識されるようにするには、手動で削除する必要がありました。
[更新 3] IDE を最初から再構成するときに、「dev_appserver.py」の代わりに「old_dev_appserver.py」を使用してアプリをローカルで実行することを忘れていました。後者はブレークポイントを有効にしません! しかし、SignedJwtAssertionCredentials のインポートの問題と関係があるようです。「dev_appserver.py」を使用すると、インポートの問題は発生しません (ブレークポイントはありません)。「old_dev_appserver.py」を使用すると、インポートの問題を再現できます。そのため、「old_dev_appserver.py」がずっと問題の一部だった可能性があります。