如何使用flask将异步请求发送到具有小超时会话的端点?

时间:2016-05-10 14:39:12

标签: python asynchronous flask

我是使用Flask进行后端开发的新手,我遇到了一个令人困惑的问题。我正在尝试将数据发送到Timeout会话为3000毫秒的端点。我的服务器代码如下。

from flask import Flask, request
from gitStat import getGitStat

import requests

app = Flask(__name__)


@app.route('/', methods=['POST', 'GET'])
def handle_data():
    params = request.args["text"].split(" ")

    user_repo_path = "https://api.github.com/users/{}/repos".format(params[0])
    first_response = requests.get(
        user_repo_path, auth=(
            'Your Github Username', 'Your Github Password'))

    repo_commits_path = "https://api.github.com/repos/{}/{}/commits".format(params[
                                                                            0], params[1])
    second_response = requests.get(
        repo_commits_path, auth=(
            'Your Github Username', 'Your Github Password'))

    if(first_response.status_code == 200 and params[2] < params[3] and second_response.status_code == 200):

        values = getGitStat(params[0], params[1], params[2], params[3])

        response_url = request.args["response_url"]

        payload = {
            "response_type": "in_channel",
            "text": "Github Repo Commits Status",
            "attachments": [
                {
                    "text": values
                }
                    ]
            }

        headers = {'Content-Type': 'application/json',
                'User-Agent': 'Mozilla /5.0 (Compatible MSIE 9.0;Windows NT 6.1;WOW64; Trident/5.0)'}

        response = requests.post(response_url, json = test, headers = headers)

    else:

        return "Please enter correct details. Check if the username or reponame exists, and/or Starting date < End date. \
                Also, date format should be MM-DD"

我的服务器代码从它接收的请求中获取参数,并从该请求的JSON对象获取参数,它提取代码的参数。此代码执行 getGitStats 函数,并将服务器代码中定义的JSON有效负载发送到它收到请求的端点。

我的问题是我需要向端点发送文本确认,表明我已收到请求,数据即将推出。这里的问题是函数 getGitStats 花了一分多钟来从Github API获取和解析数据。

我搜索了互联网,发现我需要使这个调用异步,我可以使用队列。我尝试使用 RQ RabbitMQ 来理解应用程序,但我既不理解也不能将我的代码转换为异步格式。有人可以给我指点或任何关于如何实现这个目标的想法吗?

谢谢。

------------ ------------更新

线程能够解决这个问题。创建另一个线程并在该线程中调用该函数。

1 个答案:

答案 0 :(得分:14)

如果您在请求中尝试执行异步任务,则必须决定是否需要结果/进度。

  1. 您不关心任务的结果,也不关心处理任务时是否有任何错误。您可以在线程中处理它并忘记结果。
  2. 如果您只想知道任务的成功/失败。您可以将任务的状态存储在数据库中,并在需要时进行查询。
  3. 如果你想完成任务的进展(20%完成...... 40%完成)。你必须使用更复杂的东西,如芹菜 rabbitMQ
  4. 对于你我认为选项#2更合适。您可以创建一个简单的表GitTasks。

      GitTasks
      ------------------------
      Id(PK) | Status   | Result
      ------------------------ 
       1     |Processing| -
       2     | Done     | <your result>
       3     | Error    | <error details> 
    

    你必须在python中创建一个简单的Threaded对象来处理。

     import threading  
     class AsyncGitTask(threading.Thread):
        def __init__(self, task_id, params):
            self.task_id = task_id
            self.params = params
        def run():
            ## Do processing
            ## store the result in table for id = self.task_id
    

    您必须创建另一个端点来查询任务的状态。

      @app.route('/TaskStatus/<int:task_id>')
      def task_status(task_id):
          ## query GitTask table and accordingly return data
    

    现在我们已经构建了所有组件,将它们放在主请求中。

      from Flask import url_for
      @app.route('/', methods=['POST', 'GET'])
      def handle_data():
        .....
        ## create a new row in GitTasks table, and use its PK(id) as task_id
        task_id = create_new_task_row()
        async_task = AsyncGitTask(task_id=task_id, params=params)
        async_task.start()
    
        task_status_url = url_for('task_status', task_id=task_id)
        ## This is request you can  return text saying 
        ## that "Your task is being processed. To see the progress 
        ## go to <task_status_url>"