ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FastAPI `BackgroundTasks` API 参考:响应发出后调度后台任务的声明式用法

FastAPI `BackgroundTasks` API 参考:响应发出后调度后台任务的声明式用法 FastAPIBackgroundTasksAPI 参考响应发出后调度后台任务的声明式用法【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapiBackgroundTasks是 FastAPI 提供的后台任务集合类在路径操作函数path operation function或依赖函数中将其声明为参数即可在响应发送之后调度并执行后台任务让慢操作如发邮件通知、处理上传文件不阻塞响应返回。本文基于官方 API 参考页 Background Tasks 展开结合仓库源码说明该类的导入方式、add_task()参数细节、依赖注入机制及其在请求处理链路中的完整实现流程读完后可直接在实际项目中使用声明式后台任务。类概述与导入方式BackgroundTasks表示一组将在响应发送给客户端之后被调用的后台任务集合。官方参考页 reference/background.md 给出的定义是You can declare a parameter in apath operation functionor dependency function with the typeBackgroundTasks, and then you can use it to schedule the execution of background tasks after the response is sent.它可以直接从fastapi顶层包导入无需接触 Starlettefrom fastapi import BackgroundTasks这一顶层导出由 fastapi/init.py 完成最终来源是 fastapi/background.py。从源码看BackgroundTasks是对 Starlette 同名类的薄封装# fastapi/background.pyL11-L12 class BackgroundTasks(StarletteBackgroundTasks): A collection of background tasks that will be called after a response has been sent to the client. 封装的意义在于FastAPI 会把“参数类型是BackgroundTasks”识别为依赖注入信号自动创建实例并传入你的函数——你不需要在业务代码里手动实例化或手动挂载到响应上。基础用法声明参数并添加任务最典型的用法是模拟“发送通知”接口先立即返回通知内容在后台写入对应真实场景中的发邮件、写日志、推送等。完整可运行的示例见 docs_src/background_tasks/tutorial001_py310.pyfrom fastapi import BackgroundTasks, FastAPI app FastAPI() def write_notification(email: str, message): with open(log.txt, modew) as email_file: content fnotification 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, messagesome notification) return {message: Notification sent in the background}要点拆解声明参数在路径操作函数中声明background_tasks: BackgroundTasks。FastAPI 会为该请求创建BackgroundTasks实例并注入到这个参数行为与直接声明Request参数类似。任务函数write_notification只是一个普通函数可以接收任意参数。它既可以是async def也可以是普通defFastAPI/Starlette 会分别正确地处理两者。添加任务调用background_tasks.add_task(...)把任务登记到集合中响应发出后才会真正执行。这个示例与BackgroundTasks类自身 docstring 中的官方示例fastapi/background.py完全一致可直接复制运行。add_task()的参数说明参考页对应的方法签名在 fastapi/background.pydef add_task( self, func: Callable[P, Any], # 响应发出后要调用的函数普通 def 或 async def 均可 *args: P.args, # 按顺序传给任务函数的位置参数 **kwargs: P.kwargs, # 传给任务函数的关键字参数 ) - None:第一个参数是任务函数本身可调用对象例如write_notification后续按顺序传入位置参数例如email最后可传入关键字参数例如messagesome notification。这些参数在调用add_task()时就已确定并保存等响应发送完成时才被实际传递给任务函数执行。典型适用场景官方教程 tutorial/background-tasks.md 列举了两类不需要客户端等待的“慢”操作动作之后发送邮件通知连接邮件服务器并发送通常需要数秒可以先立即返回响应邮件在后台发送数据处理例如接收到一个需要慢速处理流程的文件可先返回 “Accepted”HTTP 202文件在后台处理。与依赖注入系统配合使用BackgroundTasks与依赖注入系统完全兼容你可以在多个层级——路径操作函数、依赖dependable、子依赖等——声明BackgroundTasks参数。FastAPI 会在各处复用同一个对象实例所有层添加的后台任务会被合并到一起最后统一在响应发出后执行。示例见 docs_src/background_tasks/tutorial002_py310.py仓库中另有等价的Annotated写法 tutorial002_an_py310.pyfrom fastapi import BackgroundTasks, Depends, FastAPI app FastAPI() def write_log(message: str): with open(log.txt, modea) as log: log.write(message) def get_query(background_tasks: BackgroundTasks, q: str | None None): if q: message ffound query: {q}\n 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 fmessage to {email}\n background_tasks.add_task(write_log, message) return {message: Message sent}在这个例子中依赖get_query在请求携带查询参数q时向同一个BackgroundTasks对象追加一个“记录 query”的后台任务路径操作函数本身又追加一个使用路径参数email的后台任务两个任务都在响应发送之后依次写入log.txt且因为对象是同一个跨层添加的任务不会丢失。源码解析从参数检测到任务执行FastAPI 的“声明一个类型即可注入”并非魔法完整的处理链路可以在仓库源码中逐段验证。1. 参数识别把BackgroundTasks类型标记为后台任务参数fastapi/dependencies/utils.py 中FastAPI 在解析函数签名时按类型判断参数类别BackgroundTasks以及其 Starlette 基类被识别为专门的后台任务参数# fastapi/dependencies/utils.pyL365 elif lenient_issubclass(type_annotation, StarletteBackgroundTasks):命中后该参数的名字会被记录到Dependant.background_tasks_param_name字段中供后续注入使用。2. 依赖求解懒创建并共享同一个实例真正的实例化发生在依赖求解阶段 solve_dependencies。SolvedDependency数据类显式携带background_tasks字段L581并作为参数在子依赖递归求解间传递L591、L644这正是上面“多层依赖共享同一对象”行为的来源# fastapi/dependencies/utils.pyL715-L718 if dependant.background_tasks_param_name: if background_tasks is None: background_tasks BackgroundTasks() values[dependant.background_tasks_param_name] background_tasks注意这里的关键细节若当前请求链路中尚不存在实例background_tasks is None才新建一个BackgroundTasks()——即每个请求只创建一个实例创建后直接填入该参数的取值子依赖求解结果中的background_tasks又会向上传递background_tasks solved_result.background_tasksL652保证父级函数拿到的仍是同一个集合。3. 挂载到响应任务随响应一起“离场”请求处理完成后fastapi/routing.py 在构建响应时把收集到的任务集合挂到响应的background属性上。普通响应路径在 _build_response_args 中# fastapi/routing.pyL360-L362 response_args: dict[str, Any] { background: solved_result.background_tasks, }对于直接返回 StarletteResponse对象的路径操作原始响应分支FastAPI 同样做了兜底处理L712-L713、L2202-L2203if raw_response.background is None: raw_response.background solved_result.background_tasks也就是说即使你在端点里自己构造了Response只要依赖链上添加过后台任务FastAPI 也会把它们补挂到该响应的background上。4. 响应发送后执行响应对象携带background任务集合作为 ASGI 消息的一部分交给 ASGI 服务器从源码结构看任务的实际执行由 Starlette 的BaseHTTPResponse.background()机制完成——响应体发送完毕后按序调用任务函数协程函数直接await同步函数可推断会在后台线程中运行。FastAPI 侧的职责到“挂载”为止执行时机完全由 ASGI 生命周期保证任务绝不影响响应的返回。BackgroundTasks与BackgroundTask的区别官方教程的 “Technical Details” 一节明确说明了命名上的历史包袱tutorial/background-tasks.mdBackgroundTasks复数来自starlette.backgroundFastAPI 将其导入自己的命名空间你可以直接从fastapi导入直接导入/封装到 FastAPI 的目的是让你把BackgroundTasks作为路径操作函数参数使用时FastAPI 能自动接管全部流程就像使用Request对象一样这样做也避免了你误用starlette.background中另一个类BackgroundTask单数结尾没有s。单数版本在 FastAPI 中依然可用但你需要自己在代码中创建对象并返回一个携带了该对象的 StarletteResponse无法享受声明式注入的便利。使用边界何时该用任务队列系统官方文档给出的注意事项Caveat同样适用适合BackgroundTasks的场景需要在同一 FastAPI 应用内访问变量、对象的小任务例如发送一封邮件通知、写一段日志、执行一次轻量清洗不适合的场景重量级后台计算且不要求与请求同进程运行不需要共享内存、变量等。此时应考虑更完整的分布式任务工具如 Celery 这类需要消息/作业队列管理器RabbitMQ、Redis 等的方案它们配置更复杂但支持多进程乃至多服务器执行。判断原则很简单任务必须与当前应用进程共享内存 →BackgroundTasks任务可以被独立进程/机器消费 → 任务队列系统。参考文件文件说明docs/en/docs/reference/background.md本文对应的官方 API 参考页fastapi.BackgroundTasksfastapi/background.pyBackgroundTasks类与add_task()实现fastapi/dependencies/utils.py参数识别L365与实例创建、注入L715-L718fastapi/routing.py将任务集合挂载到响应的backgroundL360-L362、L712-L713、L2202-L2203docs_src/background_tasks/tutorial001_py310.py基础用法可运行示例docs_src/background_tasks/tutorial002_py310.py依赖注入多层合并示例docs/en/docs/tutorial/background-tasks.md官方教程适用场景、技术细节与注意事项【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表