flask_apscheduler实现定时推送飞书消息

[复制链接]
发表于 2026-2-2 20:33:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
需求场景:

  实现一个flask服务,通过接口控制一个定时任务任务(对旅店订房情况举行查抄)的开启和克制。要求定时任务完成后,可以通过飞书呆板人推送任务完成的消息。
显现效果:


  • 启动定时任务

  • 关闭定时任务

  • 飞书推送消息

代码实现:


  • 项目结构:

  • 业务代码:

    • 定时任务。先通过schedule模块实现底子的定时任务业务代码。
      1. # -*- coding:UTF-8 -*-
      2. """
      3. @ProjectName  :
      4. @FileName     : schedule_monitor_task
      5. @Description  :
      6. @Time         : 2023/9/18 9:21
      7. @Author       : Qredsun
      8. """
      9. import os
      10. import time
      11. from datetime import datetime
      12. from datetime import timedelta
      13. import schedule
      14. import functools
      15. from utils.webhook import send_message
      16. def read_check_list_from_excel(file):
      17.     try:
      18.        logger.info("业务代码")
      19.     except Exception as e:
      20.         logger.error(f'程序异常:{e}')
      21.     finally:
      22.         prompt_message = f'**酒店订房检查已完成**\n' \
      23.                          f'检查时间:{begin_time} - {end_time} \n' \
      24.                          f'检查报告已生成: {save_path}'
      25.         send_message(Environment.WEBHOOK_URL, Environment.WEBHOOK_SECRET, prompt_message)
      26. # todo  定时任务配置
      27. def catch_exceptions(cancel_on_failure = False):
      28.     def catch_exceptions_decorator(job_func):
      29.         @functools.wraps(job_func)
      30.         def wrapper(*args, **kwargs):
      31.             try:
      32.                 return job_func(*args, **kwargs)
      33.             except:
      34.                 import traceback
      35.                 traceback.format_exc()
      36.                 if cancel_on_failure:
      37.                     return schedule.CancelJob
      38.         return wrapper
      39.     return catch_exceptions_decorator
      40. # 异常捕获方法的使用
      41. @catch_exceptions(cancel_on_failure=False)
      42. def task_job(file_path):
      43.     # 定时任务
      44.     read_check_list_from_excel(file_path)
      45. file_path = r'../data/订房检查任务.xlsx'
      46. schedule.every().day.at("09:00").do(task_job, file_path)
      47. schedule.run_all()
      48. while True:
      49.     schedule.run_pending()  # 运行所有可以运行的任务
      50.     time.sleep(60 * 30)
      复制代码
    • 飞书消息推送功能实现
      1. # -*- coding:UTF-8 -*-
      2. """
      3. @ProjectName  :
      4. @FileName     : webhook
      5. @Description  : 飞书消息推送
      6. @Time         : 2023/9/17 13:36
      7. @Author       : Qredsun
      8. """
      9. import base64
      10. import hashlib
      11. import hmac
      12. import json
      13. from datetime import datetime
      14. import requests
      15. from utils.env_manager import Environment, logger
      16. WEBHOOK_URL = '机器人推送地址'
      17. WEBHOOK_SECRET = '机器人密码'
      18. def gen_sign(secret, timestamp):
      19.     # 拼接时间戳以及签名校验
      20.     string_to_sign = '{}\n{}'.format(timestamp, secret)
      21.     # 使用 HMAC-SHA256 进行加密
      22.     hmac_code = hmac.new(
      23.             string_to_sign.encode("utf-8"), digestmod=hashlib.sha256
      24.     ).digest()
      25.     # 对结果进行 base64 编码
      26.     sign = base64.b64encode(hmac_code).decode('utf-8')
      27.     return sign
      28. def send_message(WEBHOOK_URL, WEBHOOK_SECRET, MSG):
      29.     timestamp = int(datetime.now().timestamp())
      30.     sign = gen_sign(WEBHOOK_SECRET, timestamp)
      31.     params = {
      32.         "timestamp": timestamp,
      33.         "sign"     : sign,
      34.         "msg_type" : "interactive",
      35.         "card"     : {
      36.             "config"   : {
      37.                 "wide_screen_mode": True
      38.             },
      39.             "elements" : [
      40.                 {
      41.                     "tag"    : "markdown",
      42.                     "content": f"<at id=all></at> \n "
      43.                                f"{MSG}"
      44.                 },
      45.                 {
      46.                     "tag"    : "action",
      47.                     "actions": [
      48.                         {
      49.                             "tag"      : "button",
      50.                             "text"     : {
      51.                                 "tag"    : "plain_text",
      52.                                 "content": "跳转至订房检查"
      53.                             },
      54.                             "type"     : "primary",
      55.                             "multi_url": {
      56.                                 "url"        : Environment.CALL_BACK_URL,
      57.                                 "android_url": "",
      58.                                 "ios_url"    : "",
      59.                                 "pc_url"     : ""
      60.                             }
      61.                         }
      62.                     ]
      63.                 }
      64.             ],
      65.             "header"   : {
      66.                 "template": "blue",
      67.                 "title"   : {
      68.                     "content": "订房检查异常提示",
      69.                     "tag"    : "plain_text"
      70.                 }
      71.             },
      72.             "card_link": {
      73.                 "url"        : "",
      74.                 "pc_url"     : "",
      75.                 "android_url": "",
      76.                 "ios_url"    : ""
      77.             }
      78.         },
      79.     }
      80.     resp = requests.post(WEBHOOK_URL, json=params)
      81.     resp.raise_for_status()
      82.     result = resp.json()
      83.     if result.get("code") and result.get("code") != 0:
      84.         logger.error(f'飞书机器人消息 : {MSG} 发送失败:{resp.text}')
      85.     else:
      86.         logger.debug(f'飞书机器人消息 : {MSG} 发送成功')
      复制代码
    • flask_apscheduler更换schedule
      1. app.schedule_job.add_job(id="check_room", func='s_app:read_check_list_from_excel', **{
      2.     "args"   : (Environment.SRC_FILE,),
      3.     # 'trigger': 'interval',  # 指定 定时任务的类型
      4.     # 'seconds': 5  # 运行的间隔时间
      5.     # 每天九点开始执行
      6.     'trigger': 'cron',
      7.     'day'    : '*',
      8.     'hour'   : '09',
      9.     'minute' : '00',
      10.     'second' : '00'
      11. })
      12. app.schedule_job.start()  # 启动任务列表
      复制代码
    • flask服务中启动、克制接口实现
      1. from flask import Flask
      2. from utils.env_manager import Environment, logger
      3. from utils.schedule_monitor_task import read_check_list_from_excel
      4. from flask_apscheduler import APScheduler
      5. app = Flask(__name__)
      6. app.schedule_job = APScheduler()
      7. @app.route('/', methods=['get'])
      8. def hello_world():
      9.     return '酒店订房检查服务!'
      10. @app.route('/stop', methods=['get'])
      11. def stop_job():
      12.     if not app.schedule_job.get_jobs():
      13.         return '没有正在执行的订房检查任务'
      14.     else:
      15.         app.schedule_job.remove_all_jobs()
      16.         return '终止订房检查任务'
      17. class Config(object):
      18.     DEBUG = True  # flask 调试模式
      19.     """flask_apscheduler 配置"""
      20.     SCHEDULER_API_ENABLED = True  # 开放API
      21.     SCHEDULER_TIMEZONE = 'Asia/Shanghai'  # 使用上海时间
      22. @app.route('/start', methods=['get'])
      23. def start_job():
      24.     if app.schedule_job.get_jobs():
      25.         return '订房检查任务已启动'
      26.     else:
      27.         app.schedule_job.add_job(id="check_room", func='s_app:read_check_list_from_excel', **{
      28.             "args"   : (Environment.SRC_FILE,)
      29.             # 每天九点开始执行
      30.             'trigger': 'cron',
      31.             'day'    : '*',
      32.             'hour'   : '09',
      33.             'minute' : '00',
      34.             'second' : '00'
      35.         })
      36.         return '开始订房检查任务'
      37. app.config.from_object(Config)
      38. app.schedule_job.init_app(app)  # 把任务列表放入 flask
      39. app.schedule_job.start()  # 启动任务列表
      40. app.run()
      复制代码

ps:


  • 呆板人推送接口的设置:

  • 在flask的设置中将SCHEDULER_API_ENABLED设置为True,服务启动后主动加载flask_apscheduler提供的API接口:
    1. /scheduler [GET] > 获取服务根本信息
    2. /scheduler/jobs [POST json job data] > 添加新的任务
    3. /scheduler/jobs/<job_id> [GET] > 根据job_id返回任务的详细信息
    4. /scheduler/jobs [GET] > 返回全部任务的信息
    5. /scheduler/jobs/<job_id> [DELETE] > 删除任务
    6. /scheduler/jobs/<job_id> [PATCH json job data] > 更新一个已经存在的任务
    7. /scheduler/jobs/<job_id>/pause [POST] > 停息一个任务并返回任务的信息
    8. /scheduler/jobs/<job_id>/resume [POST] > 重新启动一个任务并返回任务信息
    9. /scheduler/jobs/<job_id>/run [POST] > 启动一个任务并返回任务的信息

  • 在实现定时任务的启动和关闭时,并没有直接flask_apscheduler利用自带的接口,而是通过flask_apscheduler提供的定时任务管理方法实现。尚有下面一些方法可参考利用:

    • scheduler.start()  开始任务
    • scheduler.shutdown() 克制任务
    • scheduler.pause()  停息全部任务
    • scheduler.resume() 开启任务
    • scheduler.add_listener(<callback function>,<event>) 添加监听变乱
    • scheduler.remove_listener(<callback function>) 去除监听变乱
    • scheduler.add_job(<id>,<function>, **kwargs)  添加job
    • scheduler.remove_job(<id>, **<jobstore>) 删除job
    • scheduler.remove_all_jobs(**<jobstore>)  删除全部定时任务
    • scheduler.get_job(<id>,**<jobstore>) 获取job信息
    • scheduler.modify_job(<id>,**<jobstore>, **kwargs) 修改job
    • scheduler.pause_job(<id>, **<jobstore>) 停息job
    • scheduler.resume_job(<id>, **<jobstore>)  规复job
    • scheduler.run_job(<id>, **<jobstore>) 启动job
    • scheduler.authenticate(<function>)  验证

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表