Google App EngineのOAuth2でdeferred.deferを使う方法
-
21-12-2019 - |
質問
私はデコレータを持っています:
http = httplib2.Http()
service = discovery.build('gmail', 'v1', http=http)
# Creating decorator for OAuth2 account.
decorator = appengine.oauth2decorator_from_clientsecrets(
CLIENT_SECRETS,
scope='https://www.googleapis.com/auth/gmail.readonly',
message=MISSING_CLIENT_SECRETS_MESSAGE)
.
とそれを使用するクラス:
class CSVGeneratorHandler(webapp2.RedirectHandler):
@decorator.oauth_required
def get(self):
http = decorator.http()
first_messages = service.users().messages().list(userId='me').execute(http=http)
template = JINJA_ENVIRONMENT.get_template('templates/success.html')
self.response.write(template.render({}))
.
はうまく機能します。
しかし、私がAPI要求を移動しようとすると、 service.users()。messages()。list(userid= 'Me')。タスクに(http= http)を実行(延期されます。DEFER(GET_MAILS))エラーが発生しました:「ログインが必要です」。
get_mails関数は、メインプログラムからコンテキストまたは/および資格情報を受信する必要があることを理解しています。しかし、私はそれをする方法を理解していません。
誰かが私を助けてもらえますか?
解決
数時間後に私は答えを見つけました。
まず最初にあなたはある場所に資格情報を保存する必要があります。私たちはあなたのGae私たちに特別なフィールドタイプを持っているので:
from oauth2client.appengine import StorageByKeyName
from google.appengine.ext import db
class CredentialsModel(db.Model):
credentials = CredentialsProperty()
.
次のステップは、デコレータなしでAUTHを設定し、その送信タスクをキューに送信した後にのみ設定します。
user = users.get_current_user()
flow = flow_from_clientsecrets(os.path.join(os.path.dirname(os.path.realpath(__file__)), CLIENT_SECRETS),
scope='https://www.googleapis.com/auth/gmail.readonly',
redirect_uri='http://127.0.0.1:8080/success')
auth_uri = str(flow.step1_get_authorize_url())
code = self.request.get('code')
if not code:
return self.redirect(auth_uri)
credentials = flow.step2_exchange(code)
storage = StorageByKeyName(CredentialsModel, user.user_id(), 'credentials')
storage.put(credentials)
deferred.defer(get_mails, user.user_id())
.
遅延関数の資格情報を取得することを忘れないでください!
def get_mails(user_id):
storage = StorageByKeyName(CredentialsModel, user_id, 'credentials')
credentials = storage.get()
http = httplib2.Http()
http = credentials.authorize(http)
all_messages = []
service = discovery.build('gmail', 'v1', http=http)
first_messages = service.users().messages().list(userId='me').execute()
. 所属していません StackOverflow