Python在GAE上动态生成HTML页面

时间:2013-04-09 16:42:57

标签: python html google-app-engine rest

在GAE上,我需要对PiCloud服务器进行一些REST调用,然后根据PiCloud返回值创建输出页面。但是,PiCloud处理模型需要几分钟时间。因此,我想知道我是否可以先创建一个“加载”页面,并在完成计算后,显示真实的输出页面。

详细地说,问题是我如何继续检查我的REST服务的状态,然后根据它生成不同的HTML页面。

我感谢任何建议和意见!

PS:jQuery BlockUI似乎是一个很好的例子,但它需要估计超时持续时间,这是我无法猜测的......

调用REST服务的函数:

def get_jid(pdf_t, pdf_nop, pdf_p):
    response = urlfetch.fetch(url=url, payload=data, method=urlfetch.POST, headers=http_headers) 
    jid= json.loads(response.content)['jid']
    output_st = "running"

    while output_st!="done":
        response_st = urlfetch.fetch(url='https://api.picloud.com/job/?jids=%s&field=status' %jid, headers=http_headers)
        output_st = json.loads(response_st.content)['info']['%s' %jid]['status']

    url_val = 'https://api.picloud.com/job/result/?jid='+str(jid)
    response_val = urlfetch.fetch(url=url_val, method=urlfetch.GET, headers=http_headers)
    output_val = json.loads(response_val.content)['result']
    return(jid, output_st, output_val)

生成HTML页面:

class pdfPage_loading(webapp.RequestHandler):
    def post(self):                              
        final_res=get_jid(pdf_t, pdf_nop, pdf_p)[2]
        html = html + template.render(templatepath + 'popup_pdf_eco.html', {
            'title':'Ubertool',
            'model_page':'',
            'model_attributes':'Please wait','text_paragraph':''})
        self.response.out.write(html)


class pdfPage_done(webapp.RequestHandler):
    def post(self):                              
        final_res=get_jid(pdf_t, pdf_nop, pdf_p)[2]
        html = html + template.render(templatepath + 'popup_pdf_eco.html', {
            'title':'Ubertool',
            'model_page':final_res,
            'model_attributes':'Please download your PDF here','text_paragraph':''})
        self.response.out.write(html)

app_loading = webapp.WSGIApplication([('/.*', pdfPage_loading)], debug=True)
app_done = webapp.WSGIApplication([('/.*', pdfPage_done)], debug=True)

def main():
    ##Here is the problematic part:
    if get_jid(pdf_t, pdf_nop, pdf_p)!='done':
        run_wsgi_app(app_pre)
    else:
        run_wsgi_app(app)

if __name__ == '__main__':
    main()  

1 个答案:

答案 0 :(得分:0)

首先,您不需要多个WSGIApplication处理程序。您可以根据URL和GET / POST参数来建立请求。

我会使用混合任务和Channel API:

当用户访问该页面时:

  1. 为要使用的用户创建频道令牌
  2. 进行REST API调用
  3. 启动任务(如下所述),将创建的令牌和PiCloud作业的ID传递给
  4. 显示“加载页面”并让用户使用在步骤1中创建的令牌连接到Channel API
  5. 在任务中,让它检查PiCloud作业的状态。如果状态未完成,请让任​​务设置新任务以再次调用自身,并检查作业的状态。作业完成后,将数据通过Channel API传递给用户,以便他们可以加载页面内容或重定向到将为其准备好内容的页面。

    示例状态检查代码(这是使用PiCloud中的示例代码,您可以使用自己的请求,因为您通过urlfetch获取状态 - 这仅仅是一个示例,因此您可以插入代码在需要时工作):

    import cloud
    from google.appengine.api import taskqueue
    from google.appengine.api import channel
    
    #<Your other hanlders here>
    
    class CheckStatus(webapp.RequestHandler):
      def post(self):
        job_id = self.request.get('job_id')
        token = self.request.get('token')
        status = cloud.get('status')
        if status != 'done':
           taskqueue.add(url='/checkstatus', params={'job_id': job_id, 'token': token}, method="POST", countdown=3)
           return
        channel.send_message(token, '<some message here>')
    
    app = webapp.WSGIApplication([('/done', pdfPage_done),
                                  ('/checkstatus', CheckStatus),
                                  ('/.*', pdfPage_loading)], debug=True)
    
    def main():
      run_wsgi_app(app)
    
    if __name__ == '__main__':
       main()