如何向FastAPI的APIRouter传递额外数据及多worker启动问题
如何向APIRouter传递已实例化的model、logger实例
不需要使用全局变量,有两种常用的显式传参方案:
- 方案1:封装路由生成函数(和Flask的
resource_class_kwargs逻辑最接近)
把路由定义逻辑封装到一个接收model、logger作为入参的函数中,最终返回实例化后的APIRouter对象,参数直接作用于闭包内的所有接口方法:
from fastapi import APIRouter, FastAPI # 路由生成函数 def create_api_router(model, logger): router = APIRouter(prefix="/api/v1") @router.get("/health") def health_check(): logger.info("触发健康检查请求") # 可直接使用传入的model实例做逻辑判断 return {"status": "ok", "model_available": model is not None} return router # 实例化阶段显式传参 my_model = load_your_trained_model() # 你的预加载模型实例 my_logger = init_your_logger() # 你的日志实例 api_router = create_api_router(my_model, my_logger) app = FastAPI() app.include_router(api_router)
- 方案2:使用FastAPI依赖注入
将model和logger封装为可注入的依赖,在需要使用的接口中通过Depends引入:
from fastapi import Depends, FastAPI, APIRouter # 预实例化对象 my_model = load_your_trained_model() my_logger = init_your_logger() # 定义依赖 def get_model(): return my_model def get_logger(): return my_logger router = APIRouter(prefix="/api/v1") @router.get("/health") def health_check(model = Depends(get_model), logger = Depends(get_logger)): logger.info("触发健康检查请求") return {"status": "ok", "model_available": model is not None} app = FastAPI() app.include_router(router)
自定义App类封装FastAPI实例时的多worker启动方法
uvicorn多worker模式的运行原理是:主进程启动后会在每个子进程中重新导入你指定的app对象,因此不能直接传入内存中的实例对象,需要让每个子进程都能独立导入到FastAPI实例,常用方案如下:
- 首先将自定义App的实例化逻辑放在可被导入的模块中,暴露FastAPI实例变量:
# app.py 你的自定义App实现文件 from fastapi import FastAPI class CustomApp: def __init__(self): self.fastapi_app = FastAPI() self.model = load_your_trained_model() self.logger = init_your_logger() # 注册路由 self.router = create_api_router(self.model, self.logger) self.fastapi_app.include_router(self.router) # 暴露FastAPI实例,供uvicorn导入 app = CustomApp().fastapi_app
- 两种启动方式二选一即可:
- 命令行启动:直接指定app的导入路径,设置worker数量
uvicorn app:app --workers 4 --host 0.0.0.0 --port 8000
- 代码编程式启动:注意run方法的app参数必须用字符串形式的导入路径,不能直接传app实例
# main.py import uvicorn if __name__ == "__main__": uvicorn.run("app:app", workers=4, host="0.0.0.0", port=8000)
注意:多进程模式下每个worker进程会独立执行一次CustomApp的实例化逻辑,因此每个进程会单独加载一次模型,属于正常现象,符合多进程内存不共享的特性
内容的提问来源于stack exchange,提问作者soumeng78
相关产品推荐
相关产品推荐

