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

DDD
发布: 2025-11-01 14:09:00
原创
739人浏览过

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。

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())会先执行。

运行效果

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

AppMall应用商店
AppMall应用商店

AI应用商店,提供即时交付、按需付费的人工智能应用服务

AppMall应用商店56
查看详情 AppMall应用商店
正在执行 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 应用的关键一环。

以上就是FastAPI 应用启动后执行一次性任务的正确姿势的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

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