FlaskInjector无法处理MethodView类视图启动报错求助
问题
使用FlaskInjector(0.14.0)与Flask==2.3.2,在app.py中配置如下:
app = create_app() FlaskInjector(app=app, modules=[configure]) app.run(port=8000, debug=app.config["DEVELOPMENT"])
启动时出现报错:
Traceback (most recent call last): File "Flask\venv\lib\site-packages\flask_injector\__init__.py", line 101, in wrap_class_based_view class_kwargs = fun_closure['class_kwargs'] KeyError: 'class_kwargs' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Program Files (x86)\JetBrains\PyCharm 2022.3.3\plugins\python\helpers\pydev\pydevd.py", line 1496, in _exec pydev_imports.execfile(file, globals, locals) # execute the script File "C:\Program Files (x86)\JetBrains\PyCharm 2022.3.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile exec(compile(contents+"\n", file, 'exec'), glob, loc) File "Flask\backend\app.py", line 246, in <module> FlaskInjector(app=app, modules=[configure]) File "Flask\venv\lib\site-packages\flask_injector\__init__.py", line 318, in __init__ process_dict(container, injector) File "Flask\venv\lib\site-packages\flask_injector\__init__.py", line 375, in process_dict d[key] = wrap_fun(value, injector) File "Flask\venv\lib\site-packages\flask_injector\__init__.py", line 63, in wrap_fun return wrap_class_based_view(fun, injector) File "Flask\venv\lib\site-packages\flask_injector\__init__.py", line 104, in wrap_class_based_view flask_restful_api = fun_closure['self'] KeyError: 'self'
定义的configure方法用于注册依赖绑定:
def configure(binder): binder.bind(HttpClient,to=HttpClient)
HttpClient为测试类,尝试过继承injector.Module或不继承:
from injector import Module class HttpClient(Module): def test_method(self): print("haha iam test method")
即便不在类视图中使用@inject装饰器,应用也无法构建。目标是创建如下API端点:
from flask.views import MethodView class IndexPageAPI(MethodView): """Servers basic statistics to the user once he loads index page.""" init_every_request = False @inject def get(self, http_client: HttpClient): self.http_client.test_method() return jsonify({'data': 'Index page api call'})
目前应用无法启动,请问问题出在哪里,该如何修改?
问题分析与解决方案
1. 修正HttpClient类定义
injector.Module是用来定义依赖绑定规则的类,不是业务服务类。HttpClient作为被注入的服务,不需要继承Module,直接定义为普通类即可:
# 修正后的HttpClient class HttpClient: def test_method(self): print("haha iam test method")
2. 解决版本兼容性问题
FlaskInjector 0.14.0和Flask 2.3.2存在兼容性冲突,旧版本无法正确处理Flask 2.x的类视图闭包结构,导致触发KeyError。
直接升级FlaskInjector到兼容Flask 2.x的版本:
pip install --upgrade flask-injector
最新稳定版的FlaskInjector已修复该兼容性问题,可适配Flask 2.x系列版本。
3. 调整类视图的依赖注入方式
类视图的依赖注入更推荐通过构造函数完成,而非直接在get方法参数中声明(方法注入虽支持,但构造注入兼容性更好,也符合依赖注入最佳实践):
from flask.views import MethodView from flask import jsonify from injector import inject class IndexPageAPI(MethodView): """Servers basic statistics to the user once he loads index page.""" init_every_request = False @inject def __init__(self, http_client: HttpClient): self.http_client = http_client def get(self): self.http_client.test_method() return jsonify({'data': 'Index page api call'})
4. 确保路由注册正确
注册类视图时,需使用add_url_rule将视图绑定到路由,确保Flask能识别该视图:
# 在create_app()或合适的代码位置添加路由注册 app.add_url_rule('/', view_func=IndexPageAPI.as_view('index_page'))
完成以上修改后,重新启动应用即可正常加载依赖并访问API端点。
内容的提问来源于stack exchange,提问作者Saurus
相关产品推荐
相关产品推荐

