作者:麦克煎蛋 出处:https://www.cnblogs.com/mazhiyong/ 转载请保留这段声明,谢谢!
有时候我们需要在request执行之后继续一些操作,但终端并不需要等待这些操作完成才能收到response。
其中一些场景举例如下:
1、在执行完request之后发送邮件通知。
2、收到文件之后对文件进行二次处理。
这些操作都需要一定的处理时间,但与返回给终端的response并无直接关系。
我们可以通过定义后台任务BackgroundTasks
,来实现这个功能。
使用 BackgroundTasks
首先我们需要导入BackgroundTasks
,并在路径操作函数中添加BackgroundTasks
类型的参数。
from fastapi import BackgroundTasks, FastAPI app = FastAPI() @app.post("/send-notification/{email}") async def send_notification(email: str, background_tasks: BackgroundTasks):
pass
任务函数
然后我们需要创建一个在后台任务中实际执行的函数:任务函数。
这是一个标准函数。这个函数可以是async def或者普通def的函数。
这里我们创建一个把指定内容写入文件的函数。
def write_notification(email: str, message=""): with open("log.txt", mode="w") as email_file: content = f"notification for {email}: {message}" email_file.write(content)
添加后台任务
最后我们需要把任务函数添加到后台任务中去。
from fastapi import BackgroundTasks, FastAPI app = FastAPI() def write_notification(email: str, message=""): with open("log.txt", mode="w") as email_file: content = f"notification for {email}: {message}" email_file.write(content) @app.post("/send-notification/{email}") async def send_notification(email: str, background_tasks: BackgroundTasks): background_tasks.add_task(write_notification, email, message="some notification") return {"message": "Notification sent in the background"}
.add_task()
接收以下参数信息:
- 在后台运行的任务函数(例如 write_notification)
- 任意序列的参数信息(例如 email)
- 任意键值对的参数信息(例如
message="some notification"
)
依赖注入
后台任务可以与依赖注入系统一起使用,我们可以在不同层级的依赖项中声明BackgroundTasks参数。
from typing import Optional from fastapi import BackgroundTasks, Depends, FastAPI app = FastAPI() def write_log(message: str): with open("log.txt", mode="a") as log: log.write(message) def get_query(background_tasks: BackgroundTasks, q: Optional[str] = None): if q: message = f"found query: {q} " background_tasks.add_task(write_log, message) return q @app.post("/send-notification/{email}") async def send_notification(email: str, background_tasks: BackgroundTasks, q: str = Depends(get_query)): message = f"message to {email} " background_tasks.add_task(write_log, message) return {"message": "Message sent"}