0

0

FastAPI 应用启动后执行一次性任务的正确姿势

DDD

DDD

发布时间:2025-11-01 14:09:00

|

781人浏览过

|

来源于php中文网

原创

FastAPI 应用启动后执行一次性任务的正确姿势

本文详细介绍了如何使用 fastapi 的 lifespan 事件结合 asynccontextmanager 在应用启动后、处理任何请求之前执行一次性初始化任务。通过此机制,开发者可以确保数据库连接、缓存预加载等操作在服务可用时已完成,同时避免阻塞服务器启动过程。

理解应用启动时的初始化需求

在构建基于 FastAPI 的 Web 服务时,我们经常需要在应用程序启动后、开始处理用户请求之前执行一些初始化操作。这些操作可能包括:

  • 加载配置数据
  • 建立数据库连接池
  • 预加载缓存数据
  • 启动后台任务或消费者
  • 执行其他一次性设置逻辑

直接在 if __name__ == "__main__": 块中调用这些函数,如果放在 uvicorn.run(app) 之前,会阻塞服务器启动,导致服务无法及时响应;如果放在 uvicorn.run(app) 之后,则根本不会被执行,因为 uvicorn.run(app) 是一个阻塞调用,会一直运行直到服务器关闭。因此,我们需要一个机制,让 FastAPI 框架自身来管理这些启动事件。

FastAPI 的 Lifespan 事件管理

FastAPI 提供了 lifespan 事件管理机制,它基于 Python 的 contextlib.asynccontextmanager,允许开发者定义在应用启动和关闭时执行的异步代码。这是处理一次性初始化任务的官方推荐方式。

lifespan 的核心思想是定义一个异步上下文管理器。当应用启动时,上下文管理器会执行 yield 语句之前的代码;当应用准备好接收请求时,它会 yield 控制权,此时服务开始处理请求;当应用关闭时,它会执行 yield 语句之后(即上下文退出时)的代码,用于资源清理。

示例:在 FastAPI 启动后初始化数据

假设我们有一个需求,在 FastAPI 应用启动后,需要执行一个耗时操作(例如,模拟数据加载),然后初始化一个全局变量 DATA。

Tago AI
Tago AI

AI生成带货视频,专为电商卖货而生

下载
import time
import uvicorn
from fastapi import FastAPI
from contextlib import asynccontextmanager

# 全局变量,用于存储初始化后的数据
DATA = {"value": ""}

def create_data():
    """
    模拟一个耗时的初始化函数,用于在应用启动时加载数据。
    """
    print("正在执行 create_data()...")
    time.sleep(2)  # 模拟耗时操作,例如从数据库加载数据或进行复杂的计算
    DATA["value"] = "Hello World!"
    print("create_data() 执行完毕。")

@asynccontextmanager
async def lifespan(app: FastAPI):
    """
    FastAPI 应用的生命周期管理器。
    在应用启动时执行 create_data(),并在应用关闭时执行清理操作(如果需要)。
    """
    # --- 应用启动时执行的代码 ---
    create_data()  # 在这里调用我们的初始化函数
    print("FastAPI 应用已启动,准备接收请求。")
    yield  # 应用在此处开始接收请求,yield 之前的代码在启动前完成
    # --- 应用关闭时执行的代码 ---
    print("FastAPI 应用正在关闭。")
    # 可以在这里执行清理操作,例如关闭数据库连接、释放资源等
    DATA["value"] = "" # 清理数据,模拟资源释放
    print("清理工作完成。")

# 将 lifespan 事件管理器传递给 FastAPI 应用
app = FastAPI(lifespan=lifespan)

@app.get("/")
def get_root():
    """
    一个简单的 GET 接口,返回 DATA 中存储的值。
    """
    return DATA

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

代码解析

  1. from contextlib import asynccontextmanager: 导入 asynccontextmanager 装饰器,它是创建异步上下文管理器的关键。
  2. DATA = {"value": ""}: 定义一个全局字典,用于存储初始化后的数据。
  3. def create_data():: 这是一个普通函数,包含了我们希望在应用启动时执行的逻辑。这里模拟了数据加载的耗时操作。
  4. @asynccontextmanager: 这个装饰器将 lifespan 异步生成器函数转换为一个异步上下文管理器。
  5. async def lifespan(app: FastAPI)::
    • 这个异步函数是 lifespan 事件的核心。它接收 FastAPI 应用实例作为参数。
    • create_data(): 在 yield 语句之前,create_data() 函数会被调用。这意味着在 FastAPI 应用开始处理任何 HTTP 请求之前,create_data() 会先执行并完成。
    • yield: 这是上下文管理器的关键点。当执行到 yield 语句时,lifespan 函数会暂停,并将控制权交还给 FastAPI。此时,FastAPI 应用正式启动,可以开始接收并处理客户端请求。
    • yield 之后的代码会在应用关闭时执行。这提供了一个方便的钩子来执行清理工作,例如关闭数据库连接、释放内存等。
  6. app = FastAPI(lifespan=lifespan): 在创建 FastAPI 应用实例时,通过 lifespan 参数将我们定义的 lifespan 上下文管理器传递进去。FastAPI 会在内部管理这个生命周期事件。
  7. uvicorn.run(app): 正常启动 Uvicorn 服务器。此时,lifespan 中 yield 之前的代码(即 create_data())会先执行。

运行效果

当你运行上述代码时,你会观察到以下输出顺序:

正在执行 create_data()...
create_data() 执行完毕。
FastAPI 应用已启动,准备接收请求。
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [xxxxx] using statreload
INFO:     Started server process [xxxxx]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

然后,如果你访问 http://localhost:8000,你会得到 {"value": "Hello World!"},这证明 create_data() 已经成功执行并更新了 DATA 变量。

当你按下 CTRL+C 停止服务器时,你会看到:

INFO:     Shutting down
FastAPI 应用正在关闭。
清理工作完成。
INFO:     Finished server process [xxxxx]
INFO:     Stopped reloader process [xxxxx]

这表明 yield 之后的清理代码也得到了正确执行。

注意事项

  • 异步操作: 如果你的初始化函数 create_data 内部包含异步操作(例如 await 数据库查询、网络请求),那么 create_data 函数本身也应该是一个 async def 函数,并且在 lifespan 中调用时需要使用 await create_data()。
  • 错误处理: 在 lifespan 的启动阶段(yield 之前)如果发生未捕获的异常,FastAPI 应用将无法启动。因此,建议对关键的初始化逻辑进行适当的错误处理,例如使用 try...except 块。
  • 资源清理: yield 之后的代码块是执行资源清理的理想位置。确保在这里释放所有在启动阶段获取的资源,以避免内存泄漏或资源耗尽。
  • 全局状态管理: 尽管在 lifespan 中修改全局变量是可行的,但对于更复杂的应用,考虑使用依赖注入(Dependency Injection)或 FastAPI 的 app.state 来管理应用级别的状态,以提高代码的可维护性和可测试性。app.state 允许你在应用实例上直接存储和访问状态。

总结

通过 FastAPI 的 lifespan 事件结合 asynccontextmanager,我们可以优雅且高效地管理应用的启动和关闭事件。这种机制确保了在服务正式对外提供前,所有必要的初始化工作都能顺利完成,并且在服务关闭时能够进行必要的资源清理。掌握 lifespan 是构建健壮和可维护的 FastAPI 应用的关键一环。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API

Python FastAPI 异步开发利用 async/await 关键字,通过定义异步视图函数、使用异步数据库库 (如 databases)、异步 HTTP 客户端 (如 httpx),并结合后台任务队列(如 Celery)和异步依赖项,实现高效的 I/O 密集型 API,显著提升吞吐量和响应速度,尤其适用于处理数据库查询、网络请求等耗时操作,无需阻塞主线程。

28

2025.12.22

Python 微服务架构与 FastAPI 框架
Python 微服务架构与 FastAPI 框架

本专题系统讲解 Python 微服务架构设计与 FastAPI 框架应用,涵盖 FastAPI 的快速开发、路由与依赖注入、数据模型验证、API 文档自动生成、OAuth2 与 JWT 身份验证、异步支持、部署与扩展等。通过实际案例,帮助学习者掌握 使用 FastAPI 构建高效、可扩展的微服务应用,提高服务响应速度与系统可维护性。

251

2026.02.06

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

839

2023.08.22

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

87

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

105

2025.09.18

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

382

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2106

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

357

2023.08.31

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

2

2026.03.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.8万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号