谁再不提前通知我,就直接复制我的文章然后发表,全家生孩子没屁眼。

原文链接:https://segmentfault.com/a/11...

作者:SyntaxError

1.配置

from App.tasks.DatabaseTask import send_ding_test  # 我的任务函数
from flask_apscheduler.auth import HTTPBasicAuth
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore


class Config(object):

    JOBS = [
        # interval定时执行(从start_date到end_date,间隔20s,包含首尾)
        # func也可以写字符串形式,例如:'App.tasks.DatabaseTask:send_ding_test'
        {
            'id': 'job2',
            'func': send_ding_test,
            'trigger': 'interval',
            'start_date': '2021-01-27 13:31:00',
            'end_date': '2021-01-27 13:33:00',
            'seconds': 20,
            'replace_existing': True  # 重新执行程序时,会将jobStore中的任务替换掉
        },
        # date一次执行
        {
            'id': 'job1',
            'func': send_ding_test,
            'trigger': 'date',
            'run_date': '2021-01-30 11:22:00',
            'replace_existing': True
        },
        # cron式定时调度,类似linux的crontab
        {
            'id': 'job3',
            'func': send_ding_test,
            'trigger': 'cron',
            'day_of_week': '0-6',
            'month': '*',
            'hour': '6',
            'minute': '0',
            'second': '0',
            'replace_existing': True
        }

    ]

    # 存储定时任务(默认是存储在内存中)  
    SCHEDULER_JOBSTORES  = {'default':SQLAlchemyJobStore(url='mysql+pymysql://xxx/xx')}
    # 设置时区,时区不一致会导致定时任务的时间错误
    SCHEDULER_TIMEZONE = 'Asia/Shanghai'
    # 一定要开启API功能,这样才可以用api的方式去查看和修改定时任务
    SCHEDULER_API_ENABLED = True
    # api前缀(默认是/scheduler)
    SCHEDULER_API_PREFIX = '/scheduler'
    # 配置允许执行定时任务的主机名
    SCHEDULER_ALLOWED_HOSTS = ['*']
    # auth验证。默认是关闭的,
    SCHEDULER_AUTH = HTTPBasicAuth()
    # 设置定时任务的执行器(默认是最大执行数量为10的线程池)
    SCHEDULER_EXECUTORS = {'default': {'type': 'threadpool', 'max_workers': 10}}
    # 另外flask-apscheduler内有日志记录器。name为apscheduler.scheduler和apscheduler.executors.default。如果需要保存日志,则需要对此日志记录器进行配置
    

 
 

2.初始化app

import logging
from flask import Flask
from config import Config  # 上边的配置文件
from flask_apscheduler.scheduler import APScheduler
from logging.handlers import RotatingFileHandler


# flask-apscheduler内置有日志器,为了让内部的日志器打印的内容输出,我这里做了个配置
# 创建日志记录器,指明日志保存路径,每个日志大小,保存日志文件个数上限
file_log_handler = RotatingFileHandler('logs/runserver.log', maxBytes=1024*1024*100, backupCount=5)
# 创建日志的记录格式,],日志等级,记录时间,报错位置,行数,日志信息
formatter = logging.Formatter(
    fmt="%(asctime)s - %(levelname)s - %(threadName)s:%(thread)s - %(filename)s - %(funcName)s - %(message)s",
    datefmt='%Y-%m-%d %H:%M:%S %a'
)
# 为刚创建的日志记录器设置日志记录格式
file_log_handler.setFormatter(formatter)
# 为全局日志对象添加日志记录器
logger = logging.getLogger("apscheduler")
logger.addHandler(file_log_handler)
logger.setLevel(logging.INFO)



def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    scheduler = APScheduler()
    scheduler.init_app(app)
    scheduler.start()
    
    # 配置api权限验证的回调函数
    @scheduler.authenticate
    def authenticate(auth):
        return auth['username'] == 'guest' and auth['password'] == 'guest'
    
    
app = create_app()
app.run(host='127.0.0.1', port='7788')

 
 

3.API调用

Flask-APScheduler内置了丰富的api接口,可以让开发者动态的查看和更改定时任务,非常方便。这里我找到内部的一部分源码,可以看到所有的api接口的调用方式。

    def _load_api(self):
        """
        Add the routes for the scheduler API.
        """
        # 获取定时任务信息
        self._add_url_route('get_scheduler_info', '', api.get_scheduler_info, 'GET')
        # 添加任务
        self._add_url_route('add_job', '/jobs', api.add_job, 'POST')
        # 获取任务
        self._add_url_route('get_job', '/jobs/<job_id>', api.get_job, 'GET')
        self._add_url_route('get_jobs', '/jobs', api.get_jobs, 'GET')
        self._add_url_route('delete_job', '/jobs/<job_id>', api.delete_job, 'DELETE')
        self._add_url_route('update_job', '/jobs/<job_id>', api.update_job, 'PATCH')
        self._add_url_route('pause_job', '/jobs/<job_id>/pause', api.pause_job, 'POST')
        self._add_url_route('resume_job', '/jobs/<job_id>/resume', api.resume_job, 'POST')
        # 立即执行一次定时任务
        self._add_url_route('run_job', '/jobs/<job_id>/run', api.run_job, 'POST')

 
调用方式我这里用postman演示。首先是查看定时任务状态:

yStLss.png

 
查看所有的定时任务:

ySNCz4.png

 
立刻执行一次定时任务:

ySN8eI.png

 
还有就是,这些api可以带权限验证的,还记得我在配置那里配置了一项参数是:

SCHEDULER_AUTH = HTTPBasicAuth()

增加这项配置后,所有的api调用都必须携带AUTHORIZATION。我这里说下怎么使用。在init_app那里我已经设置了用户名密码(guest,guest),在请求接口时,需要携带加密后的用户名密码,加密方式如下:

import base64

# 用户名密码用:分隔
string = "guest:guest".encode('utf-8')

a = base64.b64encode(string)
# print(a)
# b'Z3Vlc3Q6Z3Vlc3Q='
print(b"basic " + a)  # 最后必须拼接上basic
# b'basic Z3Vlc3Q6Z3Vlc3Q='

然后将这个字符串放在请求头中,请求头的键就是AUTHORIZATION:

ySaKrd.png

 

大家有什么问题,可以在文章下方留言,我看到后会立即回复
其他很常见的问题,比如定时重复执行的问题,网上已经有很多解决方案了,这里不再阐述


SyntaxError
199 声望20 粉丝