当前位置:   article > 正文

Python Flask与APScheduler构建简易任务监控_flask apscheduler

flask apscheduler

1. Flask Web

Flask诞生于2010年,是用Python语言,基于Werkzeug工具箱编写的轻量级、灵活的Web开发框架,非常适合初学者或小型到中型的 Web 项目。

Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login),都需要用第三方的扩展来实现。其 WSGI 工具箱采用 Werkzeug(路由模块),模板引擎则使用 Jinja2。这两个也是Flask框架的核心。

Python最出名的框架要数Django,此外还有Flask、Tornado等框架。虽然Flask不是最出名的框架,但是Flask应该算是最灵活的框架之一,这也是Flask受到广大开发者喜爱的原因。

1.1. 安装 Flask

pip install flask
  • 1

1.2. Flask框架结构

在这里插入图片描述

1.2.1. 路由route

路由是Web应用中访问不同页面的方式。在Flask中,我们可以通过定义不同的路由来实现不同页面的访问。

处理函数和和URL的关系,Flask通过修饰器把函数注册为路由。访问http://localhost:5000就会调用index这个视图函数

访问:http://127.0.0.1:5000,页面即可得到hello world.

在app对象上定义路由的方式如下:

@app.route('/')

def index():
	return 'Hello World!'
  • 1
  • 2
  • 3
  • 4

这个路由将会匹配根目录,并返回一个"Hello World!"的字符串。

变量规则
要给URL添加变量部分,可以把特殊字段标记为<variable_name>,这部分将会作为命令参数传递到函数。

构造URL
在Web程序中常常需要获取某个页面的URL,在Flask中需要使用url_for(‘方法名’)来构造对应方法的URL。

1.2.3. 模板

模板是Web应用中将数据呈现给用户的一种方式。在Flask中,我使用Jinja2模板引擎来渲染模板。

Jinja2 是一个 Python 模板引擎,主要用于在应用程序中生成动态内容。它由 Armin Ronacher 创建,是 Flask Web 框架默认使用的模板引擎,也广泛用于其他 Python Web 框架和项目中。

Flask默认使用Jinja2作为模板,Flask会自动配置Jinja 模板,默认情况下,模板文件需要放在templates文件夹下。

Jinja 模板和其他语言和框架的模板类似,都是通过语法将HTML文件中的特定元素替换为实际的值。类似java的JSP等模板。从下面的例子中我们应该可以看到Jinja 模板的基本语法了。代码块需要包含在{% %}块中。

使用 Jinja 模板,只需要使用render_template函数并传入模板文件名和参数名即可。

1.2.4. 运行

在 Flask 中,app.run() 方法用于运行应用的开发服务器。默认情况下,app.run() 使用的是 Werkzeug 服务器,并且只会在本地主机(127.0.0.1)上监听端口 5000。具体的默认参数如下:

app.run(
    host="127.0.0.1",  # 监听的主机地址
    port=5000,          # 监听的端口号
    debug=False,        # 是否启用调试模式
    load_dotenv=True,   # 是否加载 .env 文件
    **options           # 其他选项,例如 ssl_context 等
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如果你在应用的代码中只是简单地调用 app.run() 而没有传递参数,那么默认情况下应用会在本地主机的端口 5000 上运行,并且不启用调试模式。这通常用于在开发阶段进行测试和调试。

1.3. 创建 Flask 应用

1.3.1. 快速入门

创建一个 Python 文件(例如 app.py)来定义你的 Flask 应用:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return 'Hello, Flask!'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这个例子中,我们创建了一个名为 app 的 Flask 应用,并定义了一个简单的路由 /,该路由返回 “Hello, Flask!”。

运行 Flask 应用

在命令行中运行以下命令启动 Flask 应用:

python app.py
  • 1

你将看到输出类似于以下内容:

 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
  • 1

Flask 应用默认在 http://127.0.0.1:5000/ 上运行。在浏览器中打开这个地址,你将看到 “Hello, Flask!”。

1.3.2. 创建更复杂的路由和模板

以Flask与APScheduler构建简易任务监控应用为例,创建更多复杂的路由,并使用模板引擎(例如 Jinja2)来渲染 HTML 页面。以下是一个简单的示例:

1.3.2.1. 应用程序
import pytz

from apscheduler.schedulers.background import BackgroundScheduler
import datetime

import sys
import os
from flask import Flask, render_template
from loguru import logger
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

from PVSystem.PVAPScheduler import get_weather_data as get_weather24_data
from PVSystem.PVAPScheduler import monitor_data
from PVSystem.qweatherToDB import get_weather_data
from PVSystem.PVPowerForecastToDB import get_power_data
from PVSystem.PVForecastAPScheduler import set_pv_forecast
from PVSystem.PVTrainAPScheduler import get_weather_data as get_now_weather


logger.add("PVAPScheduler_{time}.log")

hms_dict = [{'fun':get_weather24_data,'id':'get_weather24_data','hour':None,'minute':'00','second':'20','trigger':'cron'},
            {'fun':monitor_data,'id':'monitor_data','hour':None,'minute':'00','second':'40','trigger':'cron'},
            {'fun':get_weather_data,'id':'get_weather_data','hour':'00','minute':'10','second':'00','trigger':'cron'},
            {'fun':set_pv_forecast,'id':'set_pv_forecast','hour':'00','minute':'13','second':'30','trigger':'cron'},
            {'fun':get_power_data,'id':'get_power_data','hour':'00','minute':'15','second':'00','trigger':'cron'},
            {'fun':get_now_weather,'id':'get_now_weather','hour':None,'minute':'05','second':'00','trigger':'cron'},]

app = Flask(__name__)

scheduler = BackgroundScheduler(timezone=pytz.timezone("Asia/Shanghai") )

@app.route('/')
def home():
    return 'Hello, Flask!'

@app.route('/task_list')
def task_list():
    jobs = scheduler.get_jobs()
    return render_template('task_list.html', jobs=jobs)

if __name__ == "__main__":
    # 添加任务到调度器
    for v in hms_dict:
        scheduler.add_job(v['fun'], v['trigger'],hour=v['hour'],minute = v['minute'], second=v['second'], misfire_grace_time=120,id=v['id'])

    # 启动 Flask 应用和调度器
    try:
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        pass

    # 启动 Flask 应用
    app.run(port=5002)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

在这个例子中,我们定义了一个路由 /task_list,并使用 render_template 渲染一个包含参数的 HTML 页面。

1.3.2.2. 创建模板文件

在项目的根目录下创建一个名为 templates 的文件夹,并在其中创建模板文件,例如 task_list.html

<!-- templates/task_list.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
	
    <style>
        table {
            width: 50%;
            border-collapse: collapse;
            margin-top: 20px;
        }

        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }

        th {
            background-color: #f2f2f2;
        }
    </style>	
	
</head>
<body>
    <h1>Task List</h1>

    <table>
        <thead>
            <tr>
                <th>任务名称</th>
                <th>下次开始执行时间</th>
            </tr>
        </thead>
        <tbody>
            {% for job in jobs %}
                <tr>
                    <td>{{ job.id }}</td>
                    <td>{{ job.next_run_time }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>	
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

这是一个简单的 HTML 模板,在这个模板中,我们使用 Jinja2 模板引擎来循环显示任务列表中的任务 ID 和下次运行时间,使用了 Jinja2 的模板语法。

1.3.2.3. 运行应用并访问路由

重新运行应用:

python app.py
  • 1

在浏览器中访问 `http://127.0.0.1:5002/task_list。
在这里插入图片描述

这只是一个 Flask Web 开发的简单入门,Flask 提供了更多功能,例如数据库集成、表单处理、用户认证等,可以根据项目需求逐步学习和使用。

1.3.3. 应用部署

使用 WSGI(Web Server Gateway Interface)服务器是在生产环境中部署 Flask 应用的推荐做法。WSGI 是一种标准的接口,用于定义 Web 服务器和 Python Web 应用程序之间的通信协议。通过使用专业的 WSGI 服务器,可以提高性能、可靠性和安全性。

安装 Gunicorn

pip install gunicorn
  • 1

启动 Flask 应用

在命令行中执行以下命令,使用 Gunicorn 启动应用:

gunicorn -w 4 -b 0.0.0.0:5000 run:app
  • 1
  • -w 4: 指定启动 4 个工作进程。可以根据需要调整工作进程的数量。
  • -b 0.0.0.0:5000: 指定服务器监听的地址和端口。
  • run:app: 指定运行的模块和应用对象。

这个命令告诉 Gunicorn 启动应用,监听指定的地址和端口,并使用指定数量的工作进程来处理请求。

访问 http://127.0.0.1:5000/,确保应用在 Gunicorn 下正常运行。你将不再看到 Flask 的调试信息,而是 Gunicorn 提供的日志信息。

这样,你就成功地用 Gunicorn 作为 WSGI 服务器来运行 Flask 应用。在生产环境中,可以使用类似 Nginx 或 Apache 作为反向代理,将请求转发给 Gunicorn 处理,以提供更好的性能和可扩展性。

2. Flask与APScheduler集成方案

APScheduler提供了BackgroundScheduler和BlockingScheduler两种类型的调度器,用于创建定时任务。

  • BackgroundScheduler在后台运行,不会阻塞主线程;
  • BlockingScheduler会阻塞主线程直到所有任务完成。

这里使用非阻塞BackgroundScheduler,如上文代码。

scheduler = BackgroundScheduler(timezone=pytz.timezone("Asia/Shanghai") )
  • 1

并且定义为全局变量。

3. 其他参考

Flask常用扩展包:

  • Flask-SQLalchemy:操作数据库;
  • Flask-migrate:管理迁移数据库;
  • Flask-Mail:邮件;
  • Flask-WTF:表单;
  • Flask-Bable:提供国际化和本地化支持,翻译;
  • Flask-script:插入脚本;
  • Flask-Login:认证用户状态;
  • Flask-OpenID:认证;
  • Flask-RESTful:开发REST API的工具;
  • Flask-Bootstrap:集成前端Twitter Bootstrap框架;
  • Flask-Moment:本地化日期和时间;
  • Flask-Admin:简单而可扩展的管理接口的框架

参考:
一抹浅笑. Python之flask框架. 博客园. 2019.01
我还可以熬_. Flask之jinja2模板(一). CSDN博客. 2022.10
黑马程序员Python. 如何最简单、通俗地理解Flask?. 知乎. 2022.09
范高伦. Flask框架. CSDN博客. 2019.10

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/499374
推荐阅读
相关标签
  

闽ICP备14008679号