GAE TaskQueue —— 外部服务器访问 Pull 队列的示例代码

64 阅读4分钟

使用 GAE TaskQueue REST API 从队列中提取任务到外部服务器(非 GAE 服务器)。

有没有某个库可以帮助完成这项工作?

API 足够简单,因此只需要弄清楚身份验证即可。我在使用 --dump_requestgoogle-api-python-client 中检查了 gtaskqueue_sample 发送的请求,找到了 authorization: OAuth XXX 标头。将该令牌添加到我自己的请求中确实有效,但是该令牌似乎会定期过期(可能每天),而且我无法弄清楚如何重新生成它。说到这一点,gtaskqueue_sample 本身不再起作用(对 https://accounts.google.com/o/oauth2/token 的调用失败,错误为“无法解码 JSON 对象”)。

如何处理身份验证?这是一个服务器应用程序,因此最好能生成一个可供以后使用的令牌。

2、解决方案

这个问题由来已久,但仍然适用,因此我将根据我最近的经验尝试提供一个更好的答案。可以从 App Engine 外部访问拉取任务队列,但是正如提问者所说,没有好的示例,因此这里提供了一个更深入的指南。在我的例子中,我有一个自定义的 Python 脚本,需要轮询队列以运行新作业。

在采用这种方式之前,还可以选择自己滚动安全设置,并针对 App Engine 任务队列调用创建一个简单的 Web 包装器。处理完后,我很想采用这种方式,但既然这种方式起作用,我目前还是打算使用它。

准备机器

pip install --upgrade google-api-python-client
easy_install python-gflags

准备帐户

使用 Google Cloud 控制台,创建一个已注册的应用(如果你还没有创建)。点击你的 App Engine 项目 -> API 和授权 -> 已注册的应用。你可以输入名称和应用程序类型,然后接受默认设置。创建后,记下客户端 ID 和客户端密钥以备后用。

此外,请更新同意屏幕(API 和授权 -> 同意屏幕)。请注意,你只需要该同意屏幕来首次设置 OAuth 凭证。你需要输入电子邮件地址和产品名称(我还输入了主页 URL)。

生成 OAuth 凭证

只需要生成一次凭证文件,然后将其用于 Python 脚本中的未来调用。运行此 Python 代码,它将打开浏览器并生成凭证文件。此处提供了此代码的参考。

from oauth2client.tools import run
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.file import Storage
import gflags
FLAGS = gflags.FLAGS

storage = Storage('credentials.json')

flow = OAuth2WebServerFlow(client_id='<your_client_id>',
                       client_secret='<your_client_secret>',
                       scope='https://www.googleapis.com/auth/taskqueue',
                       redirect_uri='urn:ietf:wg:oauth:2.0:oob')

credentials = run(flow, storage )

进行任务队列调用

确保已经在 App Engine 的 queue.yaml 中添加了一个拉取队列,并将其电子邮件地址用于上述 OAuth 步骤。

from oauth2client.tools import run
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.file import Storage
from apiclient.discovery import build
import httplib2

storage = Storage('credentials.json')
credentials = storage.get()
http = httplib2.Http()
http = credentials.authorize(http)
task_api = build('taskqueue', 'v1beta2')
tasks = task_api.tasks().lease(project='<your appengine project>',taskqueue='<pull queue name>', numTasks=1, leaseSecs=600).execute(http=http)
task = tasks['items'][0]
payload = task['payloadBase64']
payload = base64.b64decode(payload)

# 然后执行工作并在完成时删除任务

task_api.tasks().delete(project='s~<your appengine project>',taskqueue='<pull queue name>', task=task['id']).execute(http=http)

任务队列 API 参考文档

请注意删除调用中项目名称前面的前缀 s~。仅当我添加此前缀时才起作用,而且我认为这是一个错误。

7/1/2014 更新

实际上,还有一种更简单的方式来进行服务器到服务器的调用。这种方式不需要你使用“流程”(登录到 Google)来获取访问密钥。

准备机器

pip install --upgrade google-api-python-client
pip install pyOpenSSL

准备帐户

使用 Google Cloud 控制台,创建一个已注册的应用(如果你还没有创建)。点击你的 App Engine 项目 -> API 和授权 -> 凭证。点击“创建新的客户端 ID”,指定“服务帐号”,然后点击“创建客户端 ID”。

将会弹出一个下载框来下载你的私钥,将其保存到你的代码目录(或任何地方,我已将该文件另存为 client_key.p12)。在 Web 界面中,记下客户端 ID 和电子邮件。

替换上面的凭据代码

from oauth2client.client import SignedJwtAssertionCredentials

email = '<***>.gserviceaccount.com'
f = file('client_key.p12', 'rb')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials(email,
                                            key,
                                            scope='https://www.googleapis.com/auth/taskqueue')

这些 API 仅适用于 GAE 服务器,因为只能通过 queue.yaml 创建队列,并且实际上 API 不公开任何用于插入队列和任务或项目的 API。