FastAPI启动事件中依赖注入MsvConfig实例报错的解决方法
问题分析
你在FastAPI启动事件中尝试用Depends注入MsvConfig时触发了AttributeError: 'Depends' object has no attribute 'CORS_origins',原因是FastAPI的启动/关闭事件函数不支持直接使用Depends进行依赖注入——Depends是为请求处理流程设计的,启动事件属于应用初始化阶段,不在请求上下文的依赖注入链条里,所以参数上的Depends(MsvConfig)不会被解析,直接把Depends对象赋值给了msv_config变量,自然找不到CORS_origins属性。
解决思路
针对你的需求,有三种可行方案:
方案1:直接实例化MsvConfig
如果MsvConfig的实例化逻辑简单(比如从环境变量、本地配置文件读取,无其他依赖),可以直接在启动事件中创建实例:
def create_app() -> FastAPI: app = FastAPI() app.include_router(features.product_search.endpoints.endpoints.router) return app app = create_app() @app.on_event("startup") async def startup_event(): msv_config = MsvConfig() # 直接实例化配置类 origins = msv_config.CORS_origins app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
方案2:手动触发依赖解析(适合复杂依赖场景)
如果MsvConfig本身依赖其他资源(比如数据库连接、其他配置服务),可以用FastAPI内部的依赖解析工具手动解析:
from fastapi import FastAPI, Depends from fastapi.dependencies.utils import get_dependant, solve_dependencies def create_app() -> FastAPI: app = FastAPI() app.include_router(features.product_search.endpoints.endpoints.router) return app app = create_app() @app.on_event("startup") async def startup_event(): # 定义依赖项 dependant = get_dependant(path="/", call=MsvConfig) # 手动解决依赖,获取MsvConfig实例 values, _, _ = await solve_dependencies( request=None, dependant=dependant, body=None, scope={"type": "http"} ) msv_config = values[0] origins = msv_config.CORS_origins app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
方案3:在create_app中提前配置(推荐)
CORS中间件属于应用基础配置,完全可以在创建FastAPI实例时就完成配置,不需要等到启动事件:
def create_app() -> FastAPI: # 提前加载配置 msv_config = MsvConfig() origins = msv_config.CORS_origins app = FastAPI() # 直接添加中间件 app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(features.product_search.endpoints.endpoints.router) return app app = create_app()
这个方案最简洁,也符合FastAPI应用初始化的最佳实践,因为中间件应该在应用接收请求前就准备好。
内容的提问来源于stack exchange,提问作者Piotrek
相关产品推荐
相关产品推荐

