FastAPI利用装饰器实现定时任务

2023-10-27

因为 FastAPI 本身就是高性能异步框架,所以在不使用任何第三方定时任务模块的情况下,FastAPI 也可以很方便的实现定时任务。

创建一个 tasks.py 文件, 复制下面的装饰器代码:

import asyncio
from loguru import logger
from functools import wraps
from asyncio import ensure_future
from starlette.concurrency import run_in_threadpool
from typing import Any, Callable, Coroutine, Optional, Union

NoArgsNoReturnFuncT = Callable[[], None]
NoArgsNoReturnAsyncFuncT = Callable[[], Coroutine[Any, Any, None]]
NoArgsNoReturnDecorator = Callable[
    [Union[NoArgsNoReturnFuncT, NoArgsNoReturnAsyncFuncT]],
    NoArgsNoReturnAsyncFuncT
]


def repeat_task(
    *,
    seconds: float,
    wait_first: bool = False,
    raise_exceptions: bool = False,
    max_repetitions: Optional[int] = None,
) -> NoArgsNoReturnDecorator:
    '''
    返回一个修饰器, 该修饰器修改函数, 使其在首次调用后定期重复执行.
    其装饰的函数不能接受任何参数并且不返回任何内容.
    参数:
        seconds: float
            等待重复执行的秒数
        wait_first: bool (默认 False)
            如果为 True, 该函数将在第一次调用前先等待一个周期.
        raise_exceptions: bool (默认 False)
            如果为 True, 该函数抛出的错误将被再次抛出到事件循环的异常处理程序.
        max_repetitions: Optional[int] (默认 None)
            该函数重复执行的最大次数, 如果为 None, 则该函数将永远重复.
    '''
    def decorator(func: Union[NoArgsNoReturnAsyncFuncT, NoArgsNoReturnFuncT]) -> NoArgsNoReturnAsyncFuncT:
        '''
        将修饰函数转换为自身重复且定期调用的版本.
        '''
        is_coroutine = asyncio.iscoroutinefunction(func)
        had_run = False

        @wraps(func)
        async def wrapped() -> None:
            nonlocal had_run
            if had_run:
                return
            had_run = True
            repetitions = 0

            async def loop() -> None:
                nonlocal repetitions
                if wait_first:
                    await asyncio.sleep(seconds)
                while max_repetitions is None or repetitions < max_repetitions:
                    try:
                        if is_coroutine:
                            # 以协程方式执行
                            await func()  # type: ignore
                        else:
                            # 以线程方式执行
                            await run_in_threadpool(func)
                        repetitions += 1
                    except Exception as exc:
                        logger.error(f'执行重复任务异常: {exc}')
                        if raise_exceptions:
                            raise exc
                    await asyncio.sleep(seconds)
            ensure_future(loop())
        return wrapped
    return decorator

main.py 中调用时需要先添加 @app.on_event('startup') 装饰器,然后再添加我们自己实现的 repeat_task 装饰器:

......
from core.tasks import repeat_task
......
@app.on_event('startup')
@repeat_task(seconds=60*60, wait_first=True)
def repeat_task_aggregate_request_records() -> None:
    logger.info('触发重复任务: 聚合请求记录')
......

将重复周期改成 6 秒测试一下效果:

INFO:     Started server process [2075595]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8083 (Press CTRL+C to quit)
2022-05-31 19:31:44.065 | INFO     | apis.bases.api_logs:repeat_task_aggregate_request_records:52 - 触发重复任务: 聚合请求记录
2022-05-31 19:31:50.067 | INFO     | apis.bases.api_logs:repeat_task_aggregate_request_records:52 - 触发重复任务: 聚合请求记录
2022-05-31 19:31:56.068 | INFO     | apis.bases.api_logs:repeat_task_aggregate_request_records:52 - 触发重复任务: 聚合请求记录

以上只实现了一个定期重复执行的 repeat_task 装饰器,如果要实现更多需求,只需要照葫芦画瓢再实现几个装饰器就可以了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FastAPI利用装饰器实现定时任务 的相关文章

  • 将 pandas 数据框中的列减去其第一个值

    我需要将 pandas 数据帧的一列中的所有元素减去其第一个值 在这段代码中 pandas 抱怨 self inferred type 我猜这是循环引用 df Time df Time df Time 0 在这段代码中 pandas 抱怨为
  • 在 Python 中使用 XPath 和 LXML

    我有一个 python 脚本 用于解析 XML 并将某些感兴趣的元素导出到 csv 文件中 我现在尝试更改脚本以允许根据条件过滤 XML 文件 等效的 XPath 查询将是 DC Events Confirmation contains T
  • 如何使用pycaffe重构caffe网络

    我想要的是 加载网络后 我将分解一些特定的图层并保存新的网络 例如 原网 数据 gt conv1 gt conv2 gt fc1 gt fc2 gt softmax New net 数据 gt conv1 1 gt conv1 2 gt c
  • 如何在 Ubuntu 上安装 Python 模块

    我刚刚用Python写了一个函数 然后 我想将其做成模块并安装在我的 Ubuntu 11 04 上 这就是我所做的 创建 setup py 和 function py 文件 使用 Python2 7 setup py sdist 构建分发文
  • 如何更改充当按钮的范围的文本

    我正在为自定义 Web 应用程序编写自动化测试 我遇到了无法更改跨度文本的问题 我尝试过使用 driver execute script 但没有运气 如果我更好地了解 javascript 这确实会有帮助 据我所知 您无法单击跨度 并且列表
  • 在 Python 中使用 sec 函数的反函数

    我正在创建一个程序 用于计算从一定高度范围和设定初始速度发射射弹的最佳角度 在我需要使用的最终方程中 存在一个反 sec 函数 它导致了一些麻烦 我已经导入了数学并尝试使用 asec 无论如何 但是数学似乎无法计算反秒函数 我也明白 sec
  • 将一个时间序列插入到 pandas 中的另一个时间序列中

    我有一组定期测量的值 说 import pandas as pd import numpy as np rng pd date range 2013 01 01 periods 12 freq H data pd Series np ran
  • 将 subprocess.Popen 的输出通过管道传输到文件

    我需要启动一些长时间运行的进程subprocess Popen 并希望拥有stdout and stderr从每个自动管道到单独的日志文件 每个进程将同时运行几分钟 我想要两个日志文件 stdout and stderr 每个进程当进程运行
  • 如何使用 openpyxl 对工作簿中的 Excel 工作表/选项卡进行排序

    我需要按字母数字对工作簿中的选项卡 工作表进行排序 我在用openpyxl https openpyxl readthedocs io en default 操作工作表 您可以尝试排序workbook sheets list workboo
  • 行为:如何从另一个文件导入步骤?

    我刚刚开始使用behave http pythonhosted org behave 一个Pythonic BDD框架 使用小黄瓜语法 http docs behat org guides 1 gherkin html 行为需要一个特征 例
  • 使用循环将对象添加到列表(python)

    我正在尝试使用 while 循环将对象添加到列表中 基本上这就是我想做的 class x pass choice raw input pick what you want to do while choice 0 if choice 1 E
  • 使用 python 将文本发送到带有逗号分隔符的列

    如何使用分隔符 在 Excel 中将一列分成两列 并使用 python 命名标题 这是我的代码 import openpyxl w openpyxl load workbook DDdata xlsx active w active a a
  • 在 Windows 上使用 IPython 笔记本时出现 500 服务器错误

    我刚刚在 Windows 7 Professional 64 位上全新安装了 IPython 笔记本 我采取的步骤是 从以下位置安装 Python 3 4 1http python org http python org gt pip in
  • urllib2.urlopen() 是否实际获取页面?

    当我使用 urllib2 urlopen 时 我在考虑它只是为了读取标题还是实际上带回整个网页 IE 是否真的通过 urlopen 调用或 read 调用获取 HTML 页面 handle urllib2 urlopen url html
  • 负整数的Python表示

    gt gt gt x 4 gt gt gt print b format x x 4 100 gt gt gt mask 0xFFFFFFFF gt gt gt print b format x mask x mask 4294967292
  • FastText - 由于 C++ 扩展未能分配内存,无法加载 model.bin

    我正在尝试使用 FastText Python APIhttps pypi python org pypi fasttext https pypi python org pypi fasttext虽然 据我所知 此 API 无法加载较新的
  • WindowsError:[错误 5] 访问被拒绝

    我一直在尝试终止一个进程 但我的所有选项都给出了 Windows 访问被拒绝错误 我通过以下方式打开进程 一个python脚本 test subprocess Popen sys executable testsc py 我想杀死那个进程
  • 使用 lambda 函数更改属性值

    我可以使用 lambda 函数循环遍历类对象列表并更改属性值 对于所有对象或满足特定条件的对象 吗 class Student object def init self name age self name name self age ag
  • 使用 Doc2vec 后如何解释 Clusters 结果?

    我正在使用 doc2vec 将关注者的前 100 条推文转换为矢量表示形式 例如 v1 v100 之后 我使用向量表示来进行 K 均值聚类 model Doc2Vec documents t size 100 alpha 035 windo
  • 如何使用 Django (Python) 登录表单?

    我在 Django 中构建了一个登录表单 现在我遇到了路由问题 当我选择登录按钮时 表单不会发送正确的遮阳篷 我认为前端的表单无法从 查看 py 文件 所以它不会发送任何 awnser 并且登录过程无法工作 该表单是一个简单的静态 html

随机推荐

  • 第八章numpy之统计相关+练习题

    统计相关 次序统计 计算最小值 numpy amin a axis None out None keepdims np NoValue initial np NoValue where np NoValue Return the minim
  • 聊聊银行的信息科技岗(含各大银行薪资)

    大家好 今天跟大家聊聊薪资问题 作为技术岗 除了可以选择去互联网工作 还有一些同学会选择银行信息科技岗 我周围就有同学到工行 农行软开工作的 也有大佬去了竞争很大的总行 关于银行信息科技岗 看到这篇文章介绍的很不错 来分享给大家 这两天看了
  • 鼠标悬停改变内容-react

    用onMouseEnter onMouseLeave onMouseOver和onMouseOut属性 由于支持冒泡导致不稳定 后来更改为只经过自身触发 经过子元素不触发事件的onMouseEnter和onMouseLeave div is
  • Elasticsearch CCR源码分析(补充)

    接上篇TODO Elasticsearch CCR源码分析 上篇TODO http请求 ccr follow 接收到后 follow集群节点开始全量同步 是以snapshot的模式去拉leader集群数据的 那么是在什么时候将leader集
  • 初识CSS

    下面将学习CSS基础知识 如选择器类型 盒子模型 CSS定位 布局 伪类 伪元素 还有导航栏等 文章目录 一 何为CSS 二 CSS语法 三 CSS id和Class选择器 1 id 选择器 2 class选择器 四 CSS创建 1 如何插
  • VS2015 LINK : warning LNK4068: 未指定 /MACHINE;默认设置为 X86

    修改方法 在工程属性中 选择 配置属性 库管理器 命令行 在下面的其他选项中输入 MACHINE X64
  • 解决微信小程序报错request:fail url not in domain list

    问题 微信开发者工具能正常发送请求 在真机调试的时候发送请求报错 request fail url not in domain list 1 检查微信后台域名信息是否配置了request合法域名 2 检查微信本地设置 将不校验合法域名勾选上
  • 运动目标检测--光流法

    一 概述 运动目标检测是指当监控场景中有活动目标时 采用图像分割的方法从背景图像中提取出目标的运动区域 运动目标检测技术是智能视频分析的基础 因为目标跟踪 行为理解等视频分析算法都是针对目标区域的像素点进行的 目标检测的结果直接决定着智能视
  • maven私服搭建

    文章目录 前言 一 Nexus 二 安装nexus 2 1在Mac终端输入 如果提示没有brew命令 请先安装brew 2 2启动nexus 2 3访问web管理系统 三 nexus的配置 3 1登录后开始设置操作 3 1 1设置新密码 3
  • 笔记/Linux运维面试常见问题

    linux基础 linux的特点 免费 开源 单根目录树 多用户多任务 区分大小写 一切皆文件 不以扩展名区分文件类型 Linux的必须分区有哪些 根分区 swap分区 swap分区的作用 物理内存不足时 未使用的进程可以临时保存到swap
  • 浅谈EL表达式

    目录 EL表达式 什么是EL表达式 EL表达式的语法 EL表达式中的查找并输出 EL运算符 EL算数运算符 EL比较运算符 EL逻辑运算符 EL其他运算符 EL表达式 什么是EL表达式 EL 提供了更为简洁 方便的形式来访问变量和参数 不仅
  • 黑盒测试-等价类划分法与边界值分析法-三角形问题

    等价类划分法 等价类划分可以把全部输人数据合理划分为若干等价类 在每一个等价类中取个数据作为测试的输人条件 就可以用少量代表性的测试数据取得较好的测试效果 有效等价类 指对于程序规格说明来说 由合理的 有意义的输入数据构成的集合 利用它 可
  • 对于傅里叶变换的小结

    原本写在word中 含有一些公式不容易搬移 因此输出长图发布在博客中 个人理解有限 如有错误欢迎交流指出 关于参数化谱估计可以参考我以前的几篇博客 Yule Walker方程法参数化谱估计 Python实现版 Levinson Durbin
  • Ceres与colmap安装

    已在ubuntu18 04上成功安装ceres1 14 0和colmap ceres1 14 0基本没错 找tag里的1 14 0压缩包 因为复制的git链接都指定了下载最新版本 colmap 安装cmakelist 添加set CMAKE
  • 深入了解C/C++开发就业前景如何?

    C C 编程语言 作为编程行业里出现较早的编程语言 几十年来 因为语言灵活 数据结构丰富 具有结构化 平台移植力强 程序执行效率高等特点 广受关注与应用 深入了解C C 开发就业前景如何 即使新编程语言不断涌出 智能化水平越来越高 也无法挑
  • 牧师与恶魔过河游戏——智能提示

    前言 这次实现一个含提示功能的牧师与恶魔过河小游戏 主要在上一个版本的牧师与恶魔小游戏上进行更改 通过增加一个状态计算和改版了得寻路算法 实现向玩家提示如何胜利完成游戏 游戏主体实现思路见上一篇博客 牧师与恶魔小游戏 动作分离版 游戏效果图
  • 考研英语二大作文模板/图表作文,英语图表作文这一篇就够了

    常见图表类型 表格 它表示多种事物的相互关系 曲线 它常表示事物的变化趋势 柱状 它用来表示几种事物的变化情况及相互关系 饼状 表示各事物在总体中所占的比例及相互关系 其中 柱形图和饼形图出现的频率比较高 图表作文结构 Para 1 描述图
  • 电动车结构及其工作原理

    电动车结构及其工作原理 文章目录 电动车结构及其工作原理 电动车定义 电动车结构 电源系统 电力驱动系统 整车控制器 辅助系统 电动车可能存在的结构形式 电动车定义 纯电动汽车是完全由可充电电池 如铅酸电池 镍镉电池 镍氢电池或锂电子电池
  • Ubuntu更改下载源

    Ubuntu更改下载源 今天美滋滋的打开ubuntu准备下载一个语言包 对于英语不好的我来说 看全英文版的ubuntu系统太吃力了 感觉系统极其不友好 哈哈 然后准备下在一个语言包 但是下载速度及其的慢 只有十几kb每秒 如果按照这样的速度
  • FastAPI利用装饰器实现定时任务

    因为 FastAPI 本身就是高性能异步框架 所以在不使用任何第三方定时任务模块的情况下 FastAPI 也可以很方便的实现定时任务 创建一个 tasks py 文件 复制下面的装饰器代码 import asyncio from logur