使用 GAE TaskQueue REST API 从队列中提取任务到外部服务器(非 GAE 服务器)。
有没有某个库可以帮助完成这项工作?
API 足够简单,因此只需要弄清楚身份验证即可。我在使用 --dump_request 从 google-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。