我在python中设置了一个最基本的API结构
,即堆栈flask - connexion - flaskInjector
根据下面显示的代码。当 API 运行时,初始化 FlaskInjector 时,它会失败并显示错误消息:
注射器。CallError: Call to RequestScope。init() 失败:init() 缺少 1 个必需的位置参数:"注入器"(注入堆栈:[])
我的系统是 Ubuntu 18.04,在 conda 环境中的软件包如下:
康达列表的相关摘录:
# Name Version Build Channel
...
connexion 2.2.0 pypi_0 pypi
...
elasticsearch 7.0.1 pypi_0 pypi
fastavro 0.21.23 pypi_0 pypi
flask 1.0.2 pypi_0 pypi
flask-cors 3.0.7 pypi_0 pypi
flask-injector 0.12.0 pypi_0 pypi
flask-opentracing 1.0.0 pypi_0 pypi
flask-restplus 0.9.2 pypi_0 pypi
flask-script 2.0.6 pypi_0 pypi
flask-sqlalchemy 2.3.2 pypi_0 pypi
...
injector 0.12.0 pypi_0 pypi
...
swagger-ui-bundle 0.0.3 pypi_0 pypi
...
项目组织如下:
./app.py:
from injector import Binder
from flask_injector import FlaskInjector
from connexion.resolver import RestyResolver
import connexion
from providers.provider import ItemsProvider
def configure(binder: Binder) -> Binder:
binder.bind(
ItemsProvider,
ItemsProvider([{'Name': 'Test 1'}])
)
return binder
if __name__ == '__main__':
app = connexion.App(__name__, specification_dir='./swagger/')
app.add_api('app.yaml', resolver=RestyResolver('api'))
FlaskInjector(app=app.app, modules=[configure])
app.run(port=9090, debug=True)
./api/items.py:
from flask_injector import inject
from providers.provider import ItemsProvider
@inject(data_provider=ItemsProvider)
def search(data_provider) -> list:
return data_provider.get()
./providers/provider.py:
class ItemsProvider(object):
def __init__(self, items: list = []):
self._items = items
def get(self, number_of_items: int = 5) -> list:
if not self._items:
return []
if number_of_items > len(self._items):
number_of_items = len(self._items)
return self._items[0:number_of_items]
./swagger/app.yaml:
swagger: "2.0"
info:
title: "My first API"
version: "1.0"
basePath: /api
paths:
/items/:
get:
responses:
'200':
description: 'Fetch a list of items'
schema:
type: array
items:
$ref: '#/definitions/Item'
definitions:
Item:
type: object
properties:
id:
type: integer
format: int64
name: { type: string }
在使用 python app.py 运行应用程序时,api 服务器按预期启动:
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:9090/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 498-670-595
但是,在浏览器中寻址服务器或项目端点时,将显示以下故障堆栈:
127.0.0.1 - - [21/May/2019 08:16:31] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/app.py", line 1811, in full_dispatch_request
rv = self.preprocess_request()
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask/app.py", line 2087, in preprocess_request
rv = func()
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/flask_injector.py", line 327, in reset_request_scope_before
injector_not_null.get(request_scope_class).prepare()
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/injector.py", line 738, in get
result = scope_instance.get(key, binding.provider).get(self)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/injector.py", line 144, in get
return injector.create_object(self._cls)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/injector.py", line 789, in create_object
(), additional_kwargs, e, self._stack,)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/injector.py", line 73, in reraise
raise exception.with_traceback(tb)
File "/home/christian/.conda/envs/miccroservice/lib/python3.6/site-packages/injector.py", line 782, in create_object
init(instance, **additional_kwargs)
injector.CallError: Call to RequestScope.__init__() failed: __init__() missing 1 required positional argument: 'injector' (injection stack: [])
127.0.0.1 - - [21/May/2019 08:16:31] "GET /?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2019 08:16:31] "GET /?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2019 08:16:31] "GET /?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2019 08:16:31] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
感谢您的回答。我同时想到了一个可行的解决方案。@inject
装饰器至少在我当前的版本中不能与参数一起使用。如果我将函数更改为:
@inject
def search(dataprovider=ItemsProvider_()) -> list:
data = dataprovider.get(0)
return data
谢谢!
将喷油器版本从喷油器-0.12.0 更新到喷油器-0.17.0 解决了我的问题。
我在以下情况下收到此错误:
我在实例化烧瓶应用程序并配置注射器的模块中定义了要注入的类:
app.py
class MyClass:
def __init__(bar)
self.bar = bar
# ... instantiate flask app and injector
我将类注入到不同的模块中:
controller.py
from app import MyClass
@inject
def foo(my_object: MyClass):
return 'Something'
对我来说,解决方案是创建一个单独的模块,在其中定义与实例化注入器的模块不同的MyClass
。