【python】 通过 flask-apscheduler 实现定期执行任务

Flask-APScheduler 介绍

Flask-APScheduler 是基于 APScheduler 库开发的 Flask 拓展库。APScheduler 的全称是Advanced Python Scheduler 。本文主要通过 APScheduler 中的 cron触发器来实现定时启动任务的目的。

安装 flask_apscheduler 库

pip install flask_apscheduler

导入时报错

error: subprocess-exited-with-error

× pip subprocess to install build dependencies did not run successfully.
│ exit code: 2
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

在网上查阅相关资料,使用如下方式成功安装 flask-apscheduler。但是运行程序时,仍然识别不到flask-apscheduler 库

pip install --upgrade setuptools
pip install flask-apscheduler

基本结构

from flask import Flask
from flask_apscheduler import APScheduler


class Config():
    JOBS = [
        {
            'id': 'job1',
            'func': 'test:test',  # 第一个test为函数所在py文件名
            'args': (),           # 函数不需要参数时,可以设置为空元组,也可以直接省略
            'trigger': 'cron',    # 使用cron触发器
            'day': '*',           # * 表示每一天
            'hour': '10',
            'minute': '0',
            'second': '0'

        }
    ]
    SCHEDULER_API_ENABLED = True


def test():
    print('success!')


if __name__ == '__main__':
    app = Flask(__name__)

    app.config.from_object(Config())

    scheduler = APScheduler()
    scheduler.init_app(app)    # 将调度器对象与Flask应用程序实例(app)相关联
    scheduler.start()

    app.run(host='0.0.0.0', port=8000, debug=True)

        其中,SCHEDULER_API_ENABLED = True 用来启用 Flask-APScheduler 库的 API 功能,设置为 True 后,可以使用 API 来查看和管理已经调度的任务。例如,可以通过对 http://127.0.0.1:8000/scheduler/jobs 发送 GET 请求,来获取所有已添加的 Job 信息。(如果不需要 API 功能,可以设置为 False ,以提高安全性和性能)

前端返回结果如下:

[
  {
    "id": "job1",
    "name": "job1",
    "func": "test:test",
    "args": [],
    "kwargs": {},
    "trigger": "cron",
    "day": "*",
    "hour": "10",
    "minute": "0",
    "second": "0",
    "misfire_grace_time": 1,
    "max_instances": 1,
    "next_run_time": "2023-05-19T10:00:00+08:00"
  }
]

        app.config.from_object() 用于从一个 python 对象中加载配置变量将其应用于 Flask 应用程序。在这段代码中,通过 app.config['JOBS'] 可以获取到定义的调度任务列表,而通过 app.config['SCHEDULER_API_ENABLED'] 可以获取到 API 是否被启用。其他 Flask 扩展也可以通过这种方式使用配置变量,例如 Flask-SQLAlchemy 扩展需要从 SQLALCHEMY_DATABASE_URI 变量中获取数据库连接字符串。

应用实例

需求:每天定时检查文件夹大小,并进行管理

import os
import time

from flask import Flask
from flask_apscheduler import APScheduler


def folder_size(path):
    total = 0
    for entry in os.scandir(path):
        if entry.is_file():
            total += entry.stat().st_size
        elif entry.is_dir():
            total += folder_size(entry.path)
    return total


def mng_folder_size():
    for f in os.listdir('/home/user/video'):
        if (folder_size('/home/user/video' + f)) / 1024 * 1024 * 1024 >= 5:
            current_time = time.time()
            for i in os.listdir('/home/user/video/' + f):
                creation_time = os.path.getmtime('/home/user/video/' + f + '/' + i)
                if (current_time - creation_time) // (24 * 60 * 60) >= 7:
                    os.unlink('/home/user/video/' + f + '/' + i)
                    print(f'{i} removed.')


class Config(object):
    JOBS = [
        {
            'id': 'job1',
            'func': mng_folder_size,
            'trigger': 'cron',
            'day': '*',
            'hour': '0',
            'minute': '0',
            'second': '0'
        },
        {
            'id': 'job2',
            'func': mng_folder_size,
            'trigger': 'cron',
            'day': '*',
            'hour': '12',
            'minute': '0',
            'second': '0'
        }
    ]
    SCHEDULER_API_ENABLED = True


if __name__ == '__main__':
    app = Flask(__name__)    # 也可以写在上边

    app.config.from_object(Config())

    scheduler = APScheduler()
    scheduler.init_app(app)
    scheduler.start()

    app.run(host='0.0.0.0', port=5055, debug=True)

        folder_size() 用于计算文件夹大小。它使用递归来遍历整个目录树,判断是文件还是目录。如果是文件,直接将其大小计入 total ;如果是目录,则递归调用本函数以继续遍历其中所有的文件和子目录,并计算大小。

        os.scandir() 用于遍历指定目录下的文件和子目录。与 os.listdir() 不同,os.scandir() 返回一个迭代器对象,可以逐个访问每个目录项,并且提供了对象的一些属性和方法:

  • name : 目录项的名称(str)
  • path : 目录项的路径(str)
  • is_file() : 判断目录项是否为普通文件
  • is_dir() : 判断目录项是否为目录
  • is_symlink() : 判断目录项是否为符号链接
  • stat() : 获取目录项的状态信息

遇到的问题

D:\ProgramData\Anaconda3\lib\site-packages\apscheduler\util.py:428: PytzUsageWarning: The localize method is no longer necessary, as this time zone supports the fold attribute (PEP 495). For more details on migrating to a PEP 495-compliant implementation, see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
return tzinfo.localize(dt)

在Config类中加入 SCHEDULER_TIMEZONE = 'Asia/Shanghai'  即可解决时区问题。

补充:APScheduler

from apscheduler.schedulers.background import BackgroundScheduler

def test():
    print('success!')

sche = BackgroundScheduler(timezone='Asia/Shanghai')

# 每十分钟执行一次(如果需要参数,直接args=(a,b,...))
sche.add_job(test, 'interval', minutes=10, id='test1', replace_existing=True)
# 每天7点执行一次
sche.add_job(test, 'cron', day='*', hour=7, id='test2', replace_existing=True)

sche.start()

      replace_existing=True 表示,当存在相同ID的作业时,将对之前的作业进行覆盖,而不会同时存在两个相同作业ID的作业;如果 replace_existing 参数设置为 False 或未指定(默认值为 False),则如果尝试添加一个具有相同作业ID的新作业,APScheduler会引发 JobExistsError 异常,表示作业已存在,并且不会替换现有的作业。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值