FastAPI(41)- Background Task 后台任务

简介: FastAPI(41)- Background Task 后台任务

后台任务


  • 顾名思义,可以在返回响应后运行后台任务
  • 这对于需要在请求后执行特定的操作很有用,且客户端并不需要在接收响应之前等待该操作完成

 

常见的栗子

  • 发送电子邮件通知,由于连接到电子邮件服务器并发送电子邮件往往会比较“缓慢”(几秒钟),因此可以立即返回响应并在后台发送电子邮件通知
  • 假设您到一个必须经过缓慢处理的文件,可以先返回“已接受”(HTTP 202)响应并在后台处理它

 

实际栗子


创建后台任务要用到的函数

  • 创建一个作为后台任务运行的函数,就是一个普通函数
  • 可以加 async 也可以不加,FastAPI 将会正确处理它


import time
def write_notification(email: str, message: str = ""):
    # 1、模拟和邮件服务器建立连接
    time.sleep(3)
    with open("text.txt", mode="w") as f:
        # 2、模拟发送邮件
        content = f"message is {message}"
        f.write(content)
        print(content)


添加后台任务

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/29 7:11 下午
# file: 35_background_task.py
"""
import time
import uvicorn
from fastapi import FastAPI, BackgroundTasks
app = FastAPI()
def write_notification(email: str, message: str = ""):
    # 1、模拟和邮件服务器建立连接
    time.sleep(3)
    with open("text.txt", mode="w") as f:
        # 2、模拟发送邮件
        content = f"message is {message}"
        f.write(content)
        print(content)
@app.post("/email/{email}")
async def send_email(
        email: str,
        # 指定参数类型为 BackgroundTasks
        background_task: BackgroundTasks
):
    # 添加后台任务
    # 第一个参数:可调用对象,一般就是函数
    # 后面的参数:write_notification 函数所需要的参数
    background_task.add_task(write_notification, email, message="test_message")
    return {"message": "Notification sent in the background"}
if __name__ == '__main__':
    uvicorn.run(app="35_background_task:app", reload=True, host="127.0.0.1", port=8080)


后台任务结合依赖项


#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/29 7:11 下午
# file: 35_background_task.py
"""
import time
from typing import Optional
import uvicorn
from fastapi import FastAPI, BackgroundTasks, Depends
app = FastAPI()
# 后台任务函数
def write_log(message: str):
    with open("log.txt", mode="a") as log:
        log.write(message)
# 依赖项函数
async def get_query(
        background_task: BackgroundTasks,
        q: Optional[str] = None,
):
    # 如果 q 有值才执行后台任务
    if q:
        message = f"found query: {q}\n"
        background_task.add_task(write_log, message)
@app.post("/email_depends/{email}")
async def send_email(
        email: str,
        background_task: BackgroundTasks,
        q: str = Depends(get_query)
):
    # 执行一次后台任务
    message = f"message to {email}\n"
    background_task.add_task(write_log, message)
    return {"message": "Message sent"}
if __name__ == '__main__':
    uvicorn.run(app="35_background_task:app", reload=True, host="127.0.0.1", port=8080)


  • 后台任务可以在任意地方使用,比如路径操作、依赖项、子依赖项...
  • FastAPI 会将所有后台任务合并在一起,然后在后台会按 add_task 的顺序运行

 

查看 BackgroundTasks 源码


image.png

  • BackgroundTasks 是继承 BackgroundTask,而 BackgroundTask 是直接来自 starlette.background
  • add_task() 第一个参数 func 类型是 Callable,可调用对象,一般传函数就好啦
  • 内部会声明一个 BackgroundTask 对象,自动调用它的 __call__ 方法
  • 可以看到,最终会执行 func()
  • func() 函数参数就是 add_task() 函数除第一个参数以外的参数

 

BackgroundTasks 注意事项


  • 如果需要执行繁重的后台计算,且可能需要多个进程运行(例如,不需要共享内存、变量等),使用其他更大的工具,如:Celery,效果可能会更好
  • 它们往往需要更复杂的配置、消息/作业队列管理器,如 RabbitMQ 或 Redis,它们允许在多个进程中运行后台任务,尤其是在多个服务器中
  • 但是,如果需要从同一个 FastAPI 应用程序访问变量和对象,或者需要执行小型后台任务(例如发送电子邮件通知),只需使用 BackgroundTasks
相关文章
|
API 数据库
FastAPI(63)- Concurrency and async / await 并发、异步/等待
FastAPI(63)- Concurrency and async / await 并发、异步/等待
662 0
|
Java Android开发
Android Priority Job Queue (Job Manager):后台线程任务结果传回前台(三)
 Android Priority Job Queue (Job Manager):后台线程任务结果传回前台(三) 在附录文章4,5的基础上改造MainActivity.java和MyJob.java,改造后的代码,将使MyJob在后台完成线程任务后返回数据给前台。
1023 0
|
安全 Windows 容器
UWP -- Background Task 深入解析
原文:UWP -- Background Task 深入解析 1. 重点 锁屏问题 从 Windows 10 开始,用户无须再将你的应用添加到锁屏界面,即可利用后台任务,通用 Windows 应用必须在注册任何后台触发器类型之前调用 RequestAccessAsync: await BackgroundExecutionManager.
1233 0
|
消息中间件
celery--调用异步任务的三种方法和task参数
celery--调用异步任务的三种方法和task参数
|
vr&ar Swift
大师学SwiftUI第9章Part 1 - 异步并发之Task、Async、Await和错误
苹果系统借助现代处理器的多核可同步执行多条代码,提升同一时间内程序所能执行的任务。例如,一段代码从网上下载文件,另一段代码可以在屏幕上显示进度。此时,我们不能等待第一个执行完后再执行第二个,而必须要同步执行这两个任务。
253 0
|
Java Android开发
Android Priority Job Queue (Job Manager):多重不同Job并发执行并在前台获得返回结果(四)
 Android Priority Job Queue (Job Manager):多重不同Job并发执行并在前台获得返回结果(四) 在Android Priority Job Queue (Job Manager)中,如果两个或者若干多个完全不同的Job子任务并发执行,如何在前台获得返回结果呢?现在给出一个例子说明。
961 0
|
Java 调度 Android开发
后台任务队列管理神器 Android-Priority-Job-Queue
有人说“Android的开发,玩的就是多线程”。从某个角度来说的确如此,现在的App被设计的越来越复杂,相信很多开发人员都因大量而又复杂的后台任务(background work)而焦头烂额:Async-Task和Activity的生命周期太过于耦合...
1436 0
|
分布式计算 Spark
Spark Job的提交与task本地化分析(源码阅读八)
  我们又都知道,Spark中任务的处理也要考虑数据的本地性(locality),Spark目前支持PROCESS_LOCAL(本地进程)、NODE_LOCAL(本地节点)、NODE_PREF、RACK_LOCAL(本地机架)、ANY(任何)几种。
1019 0
|
Java C# vr&ar
C# Task用法
原文:C# Task用法 1、Task的优势   ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便。比如:   ◆ ThreadPool不支持线程的取消、完成、失败通知等交互性操作;   ◆ ThreadPool不支持线程执行的先后次序;   以往,如果开发者要实现上述功能,需要完成很多额外的工作,现在,FCL中提供了一个功能更强大的概念:Task。
1668 0

热门文章

最新文章