Python异步处理返回进度——使用Flask实现进度条

yizhihongxing

本文将详细讲解如何使用 Flask 框架实现 Python 异步处理返回进度,并对进度进行可视化展示,以进度条形式向用户展示异步处理的进度。本文将分为两个部分来讲解,第一部分将介绍如何使用 Flask 实现异步处理并返回进度,第二部分将介绍如何使用 JavaScript 和 Bootstrap 实现进度条。

第一部分:Flask 实现异步处理返回进度

1. 准备工作

我们首先需要安装 Flask 和 Celery,你可以使用 pip 命令来安装,如下所示:

pip install flask celery

2. 建立 Flask 应用

在 Flask 中使用异步处理需要使用 Celery 库,因此我们需要在应用中初始化 Celery。我们可以使用如下代码来初始化 Celery:

from celery import Celery
from flask import Flask

app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379',
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379'

celery = Celery(
    app.name,
    broker=app.config['CELERY_BROKER_URL'],
    backend=app.config['CELERY_RESULT_BACKEND']
)
celery.conf.update(app.config)

在上面的代码中,我们使用了 Redis 作为消息队列,因此需要安装 Redis 并启动 Redis 服务。如果你使用的是其他消息队列,例如 RabbitMQ,也可以在上面的代码中进行配置。

3. 实现异步任务

现在我们来实现异步任务,下面是一个简单的异步任务的代码:

import time
from celery import Celery

celery = Celery('tasks', broker='redis://localhost:6379', backend='redis://localhost:6379')

@celery.task(bind=True)
def long_task(self):
    """Background task that runs a long function with progress reports."""
    verb = ['Starting up', 'Booting', 'Repairing', 'Loading', 'Checking']
    adjective = ['master', 'radiant', 'silent', 'harmonic', 'fast']
    noun = ['solar array', 'particle reshaper', 'cosmic ray', 'orbiter', 'bit']
    message = ''
    total = 100

    for i in range(total):
        if not message or i % 3 == 0 or i == total - 1:
            message = f'{random.choice(verb)} {random.choice(adjective)} {random.choice(noun)}...'
        self.update_state(state='PROGRESS',
                          meta={'current': i, 'total': total, 'status': message})
        time.sleep(1)
    return {'current': 100, 'total': 100, 'status': 'Task completed!', 'result': 42}

在上面的代码中,我们定义了一个名为 long_task 的异步任务,该任务会模拟一个长时间运行的进程,并会每秒返回一次运行进度。在每次更新进度的时候,我们会使用 self.update_state() 方法来更新异步任务的状态。

4. 建立路由

现在我们需要建立一个路由来启动异步任务,并将异步任务的进度发送给客户端。下面是路由的代码:

from ..tasks import long_task

@app.route('/longtask', methods=['POST'])
def longtask():
    task = long_task.delay()
    return jsonify({}), 202, {'Location': url_for('taskstatus', task_id=task.id)}

@app.route('/status/<task_id>')
def taskstatus(task_id):
    task = long_task.AsyncResult(task_id)
    if task.state == 'PENDING':
        # Job did not start yet
        response = {
            'state': task.state,
            'current': 0,
            'total': 1,
            'status': 'Pending...'
        }
    elif task.state != 'FAILURE':
        # Job is running
        response = {
            'state': task.state,
            'current': task.info.get('current', 0),
            'total': task.info.get('total', 1),
            'status': task.info.get('status', '')
        }
        if 'result' in task.info:
            response['result'] = task.info['result']
    else:
        # Job failed
        response = {
            'state': task.state,
            'current': 1,
            'total': 1,
            'status': str(task.info)
        }

    return jsonify(response)

在上面的代码中,我们建立了两个路由,第一个路由是用来启动异步任务的,它会返回一个 202 Accepted 响应,表示任务已经被接受,但尚未完成。在该路由处理函数中,我们调用 long_task.delay() 方法来启动异步任务,并将任务 ID 保存在响应头的 Location 字段中,客户端可以使用这个 URL 检查任务的状态。

第二个路由用来返回异步任务的状态。我们首先使用任务 ID 获取任务对象,然后检查任务的状态。如果任务还没有开始,我们将返回一个状态为 PENDING 的响应。如果任务正在运行,我们返回当前任务的进度和状态。如果任务已经完成,我们返回状态为 SUCCESS,并且包含任务最终的结果。

第二部分:使用 JavaScript 和 Bootstrap 实现进度条

在本部分中,我们将使用 JavaScript 和 Bootstrap 来实现进度条。我们需要在客户端向服务器发送 HTTP 请求来获取异步任务的状态,并将异步任务的进度可视化展示。

1. 发送 HTTP 请求

我们可以使用 jQuery 来向服务器发送 HTTP 请求,并且定期检查异步任务的状态。下面是向服务器发送 HTTP 请求的代码:

function update_progress() {
    $.getJSON('{{ url_for('taskstatus', task_id=task_id) }}', function(data) {
        var percentage = Math.floor(data.current / data.total * 100);
        $('.progress-bar').css('width', percentage + '%');
        $('.progress-bar').text(percentage + '%');
        if (data.state != 'SUCCESS' && data.state != 'FAILURE') {
            setTimeout(update_progress, 1000);
        }
    });
}

在上面的代码中,我们首先使用 $.getJSON() 方法向服务器发送 HTTP 请求,并获取异步任务的状态。然后我们使用异步任务的进度计算百分比,并更新进度条的宽度和文本。

如果任务还没有完成,我们将使用 JavaScript 的 setTimeout() 方法定期检查任务的状态,以获取最新的进度信息。

2. 初始化进度条

在页面加载后,我们需要初始化进度条的状态。下面是初始化进度条的代码:

$(document).ready(function() {
    update_progress();
});

在上面的代码中,我们使用了 jQuery 的 $(document).ready() 方法,在页面加载完成后调用 update_progress() 函数来初始化进度条的状态。

3. HTML 代码

下面是包含进度条的 HTML 代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Long Task</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="container">
    <h1>Long Task</h1>
    <div class="progress">
        <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
            0%
        </div>
    </div>
</div>
<script>
    var task_id = '{{ task_id }}';
    function update_progress() {
        $.getJSON('{{ url_for('taskstatus', task_id=task_id) }}', function(data) {
            var percentage = Math.floor(data.current / data.total * 100);
            $('.progress-bar').css('width', percentage + '%');
            $('.progress-bar').text(percentage + '%');
            if (data.state != 'SUCCESS' && data.state != 'FAILURE') {
                setTimeout(update_progress, 1000);
            }
        });
    }
    $(document).ready(function() {
        update_progress();
    });
</script>
</body>
</html>

在上面的代码中,我们首先引入了 Bootstrap 的 CSS 文件和 jQuery 库,并定义了包含进度条的 HTML 代码。我们使用 Flask 的 url_for() 函数来动态生成路由 URL,并通过 JavaScript 设置了任务 ID。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python异步处理返回进度——使用Flask实现进度条 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • 浅谈pycharm下找不到sqlalchemy的问题

    下面是“浅谈pycharm下找不到sqlalchemy的问题”的完整攻略: 问题描述: 在PyCharm中,使用import导入sqlalchemy时出现ModuleNotFoundError的错误提示,报告找不到该模块的路径。例如: import sqlalchemy # 报错信息 ModuleNotFoundError: No module named …

    Flask 2023年5月15日
    00
  • Flask带参URL传值的实现方法

    下面是完整的攻略,包含两个示例说明。 Flask带参URL传值的实现方法 在基于Flask框架构建Web应用程序的开发中,要实现将参数传递给URL的功能,Flask提供了多种实现方法。下面分别对这些方法进行详细的讲解。 方法1:基于URL路径传递参数 这是一种常见的URL传递参数的方式,在URL路径中添加参数,可以通过Flask提供的URL规则,解析出参数并…

    Flask 2023年5月16日
    00
  • 一文带你学会Python Flask框架设置响应头

    以下是详细的Python Flask框架设置响应头攻略。 什么是响应头? 在HTTP协议中,请求和响应分别由请求头和响应头两部分组成。其中,响应头包含一些元信息,用于描述响应中所包含的实体,如数据类型、编码方式等。 Flask框架设置响应头 在Python Flask框架中,设置响应头非常简单。可以通过Flask框架提供的make_response()函数手…

    Flask 2023年5月16日
    00
  • .net任务调度框架FluentScheduler简介

    .NET任务调度框架FluentScheduler简介 简介 FluentScheduler是一款基于.NET的任务调度框架,可以提供简单易用的API,支持多种类型的任务,可以满足各种复杂的任务调度需求。使用FluentScheduler可以省去很多手动编写任务调度代码的工作,提高了编码效率。 安装 使用NuGet包管理器或在Visual Studio的包管…

    Flask 2023年5月16日
    00
  • 使用Vue.js和Flask来构建一个单页的App的示例

    下面我会详细讲解使用Vue.js和Flask来构建一个单页App的示例,包含两个示例说明。 示例1:使用Vue.js和Flask来搭建前后端分离的Todo应用 前端Vue.js 使用Vue CLI创建项目 vue create todo-vue 安装axios npm install axios 编写Todo.vue组件 <template> &…

    Flask 2023年5月16日
    00
  • 使用flask如何获取post请求参数

    获取POST请求参数是常见的需求,在使用Flask框架开发Web应用时,也需要处理POST请求中携带的参数,本文将详细讲解使用Flask如何获取POST请求参数的完整攻略,并提供两条相关的示例,方便读者参考。 获取POST请求参数的方法 Flask中获取POST请求参数的方法主要有以下三种: 使用request.form对象 使用request.get_js…

    Flask 2023年5月16日
    00
  • 浅谈flask截获所有访问及before/after_request修饰器

    下面是“浅谈flask截获所有访问及before/after_request修饰器”的完整攻略和示例说明。 这篇文章的目的 本文旨在介绍如何使用Flask中的before_request和after_request修饰器方法,截获所有对网站的访问请求,并在请求处理前或请求处理后做出一些操作。 Flask中的before_request和after_reque…

    Flask 2023年5月16日
    00
  • Flask 文件上传方法(详解版)

    Flask 是一个轻量级的 Web 框架,提供了简洁的 API 和易于使用的工具,使得开发 Web 应用程序变得更加简单。 在本文中,我们将深入探讨 Flask 中的文件上传功能。 首先,在 Flask 中使用文件上传,需要用到 werkzeug 模块的 FileStorage 类。FileStorage 可以将上传的文件转换为特定类型的表示,以便在应用程序…

    Flask 2023年3月13日
    00
合作推广
合作推广
分享本页
返回顶部