fastapi: 有父应用和子应用时,lifespan应该写在哪里?
一,问题
我的项目中有一个父应用两个子应用,lifespan加在子应用上,但代码未被执行,应该怎么做?
二,原因:
在 FastAPI 中,如果你使用了子应用(Sub-apps)(即通过 app.mount("/sub", sub_app) 挂载),子应用自带的 lifespan 默认是不会被自动触发的。
这是 FastAPI 的一个已知设计:只有主应用(父应用)的 lifespan 会被 ASGI 服务器(如 Uvicorn)直接调用
三,解决:
既然父应用掌控了全局的生命周期,那么只需要在父应用的
lifespan 函数里,手动调用两个子应用的初始化逻辑。为了保持代码高内聚,可以将子应用的初始化逻辑封装成普通函数
代码:
from contextlib import asynccontextmanager
from fastapi import FastAPI
# --- 子应用 1 的代码 ---
sub_app1 = FastAPI()
def init_sub_app1():
# 执行子应用 1 的初始化,例如创建图片目录
import os
os.makedirs("/var/www/uploads/images", exist_ok=True)
print("子应用 1 初始化成功")
# --- 子应用 2 的代码 ---
sub_app2 = FastAPI()
def init_sub_app2():
# 执行子应用 2 的初始化,例如创建缓存目录
import os
os.makedirs("/var/www/uploads/cache", exist_ok=True)
print("子应用 2 初始化成功")
# --- 父应用(主应用)的代码 ---
@asynccontextmanager
async def parent_lifespan(app: FastAPI):
# 1. 在这里统一调用子应用的初始化函数
init_sub_app1()
init_sub_app2()
yield # 整个项目开始运行
# 2. 如果有需要,在这里写关闭时的清理逻辑
# 创建父应用并挂载
app = FastAPI(lifespan=parent_lifespan)
# 挂载子应用
app.mount("/sub1", sub_app1)
# app.mount("/sub2", sub_app2)
浙公网安备 33010602011771号