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

kok*_*een 11 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"
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢.

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

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

avi*_*tor 21

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

  1. 您不关心任务的结果,也不关心处理任务时是否有任何错误.您可以在Thread中处理它并忘记结果.
  2. 如果您只想知道任务的成功/失败.您可以将任务的状态存储在数据库中,并在需要时进行查询.
  3. 如果你想要完成任务的进展(20%完成...... 40%完成).你必须使用像celery,rabbitMQ这样更复杂的东西.

对你而言,我认为选项#2更合适.您可以创建一个简单的表GitTasks.

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

你必须在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
Run Code Online (Sandbox Code Playgroud)

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

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

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

  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>"
Run Code Online (Sandbox Code Playgroud)