flask_injector
flask_injector copied to clipboard
Strange exception when open swggaer doc -> TypeError('Injecting Any is not supported')
Hi! I am facing very strange behaviour when trying to open swgger doc provided by flask smorest. When trying to open swagger page (http://127.0.0.1:5001/application/swagger-ui) application falls down with error TypeError('Injecting Any is not supported').
I have removed all bindings to make example more understandable and clear, so sources:
from flask import Flask
from flask.views import MethodView
from flask_injector import FlaskInjector
from flask_smorest import Api, Blueprint
healthcheck_blueprint = Blueprint("healthcheck", __name__, description="App status checking")
def setup_app_injector(flask_app: Flask) -> None:
FlaskInjector(app=flask_app)
@healthcheck_blueprint.route("/healthcheck")
class HealthcheckView(MethodView):
@healthcheck_blueprint.response(status_code=200)
def get(self): # type: ignore
"""Simple healthcheck"""
return {"project": "test_injector"}
def create_flask_app() -> Flask:
flask_app = Flask(__name__)
class Config:
OPENAPI_VERSION = "3.0.2"
OPENAPI_URL_PREFIX = "/application"
OPENAPI_SWAGGER_UI_PATH = "/swagger-ui"
OPENAPI_SWAGGER_UI_VERSION = "3.24.2"
OPENAPI_SWAGGER_UI_URL = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/"
OPENAPI_REDOC_PATH = "redoc"
flask_app.config["API_TITLE"] = "test_injector"
flask_app.config["API_VERSION"] = "v1"
flask_app.config.from_object(Config)
api = Api(app=flask_app)
api.register_blueprint(healthcheck_blueprint, url_prefix="/application")
setup_app_injector(flask_app=flask_app)
return flask_app
app = create_flask_app()
def main() -> None:
local_runtime_configuration: dict[str, int | bool] = {"port": 5001, "debug": True}
app.run(**local_runtime_configuration) # type: ignore[arg-type]
if __name__ == "__main__":
main()
My pyproject:
[tool.poetry]
name = "test-injector"
version = "0.1.0"
description = ""
authors = []
readme = "README.md"
packages = [{include = "test_injector"}]
[tool.poetry.dependencies]
python = "^3.11"
flask = "2.2.3"
flask-smorest = "0.40.0"
injector = "0.20.1"
flask-injector = "0.14.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Everything works fine if remove injector (comment line 40 setup_app_injector(flask_app=flask_app)
).
Full trace:
Traceback (most recent call last):
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 637, in get_binding
return self._get_binding(interface, only_this_binder=is_scope or is_assisted_builder)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 631, in _get_binding
raise KeyError
KeyError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask/app.py", line 2551, in __call__
return self.wsgi_app(environ, start_response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask/app.py", line 2531, in wsgi_app
response = self.handle_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask/app.py", line 2528, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask/app.py", line 1825, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask/app.py", line 1823, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask/app.py", line 1799, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask_injector/__init__.py", line 45, in wrapper
return im(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask_smorest/spec/__init__.py", line 139, in _openapi_swagger_ui
return flask.render_template(
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask/templating.py", line 147, in render_template
return _render(app, template, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask/templating.py", line 130, in _render
rv = template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/jinja2/environment.py", line 1301, in render
self.environment.handle_exception()
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask_smorest/spec/templates/swagger_ui.html", line 18, in top-level template code
url: "{{ url_for('api-docs.openapi_json') }}",
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/flask_injector/__init__.py", line 89, in wrapper
return injector.call_with_injection(callable=fun, args=args, kwargs=kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 999, in call_with_injection
dependencies = self.args_to_inject(
^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 91, in wrapper
return function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 1047, in args_to_inject
instance: Any = self.get(interface)
^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 932, in get
binding, binder = self.binder.get_binding(interface)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 646, in get_binding
binding = self.create_binding(interface)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 560, in create_binding
provider = self.provider_for(interface, to)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dreamer/Projects/Development/test_injector/venv/lib/python3.11/site-packages/injector/__init__.py", line 571, in provider_for
raise TypeError('Injecting Any is not supported')
For someone who facing similiar problem -> Add flasgger to provide openapi documentation to your application.
Hey @M1LKYWVYs, thank you for a really precise and well written bug report – it's appreciated. I'm sorry you're experiencing issues.
This library does some shady things behind the scenes to make things work and that will interact weirdly with some other libraries.
I don't have resources to investigate this for the time being, unfortunately.
Hi, I am facing the same issue. According to my debugger it is related to the url_for method which 7th parameter **values has a type hint "t.Any". Were you able to find a workaround by chance?
Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 637, in get_binding return self._get_binding(interface, only_this_binder=is_scope or is_assisted_builder) File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 631, in _get_binding raise KeyError KeyError
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 2551, in call return self.wsgi_app(environ, start_response) File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 2531, in wsgi_app response = self.handle_exception(e) File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 2528, in wsgi_app response = self.full_dispatch_request() File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1825, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1823, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1799, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) File "/home/bartolomeo/aeh/zjo-pwa/APZ-CeneoScrapper/flask_app/app/services/decorators.py", line 15, in decorated_function return func(*args, **kwargs) File "/home/bartolomeo/aeh/zjo-pwa/APZ-CeneoScrapper/flask_app/app/controllers/accounts/routes.py", line 53, in login return render_template("accounts/login.html", form=form) File "/usr/local/lib/python3.8/dist-packages/flask/templating.py", line 147, in render_template return _render(app, template, context) File "/usr/local/lib/python3.8/dist-packages/flask/templating.py", line 130, in _render rv = template.render(context) File "/usr/local/lib/python3.8/dist-packages/jinja2/environment.py", line 1301, in render self.environment.handle_exception() File "/usr/local/lib/python3.8/dist-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/bartolomeo/aeh/zjo-pwa/APZ-CeneoScrapper/flask_app/app/templates/accounts/login.html", line 1, in top-level template code {% extends "base.html" %} File "/home/bartolomeo/aeh/zjo-pwa/APZ-CeneoScrapper/flask_app/app/templates/base.html", line 13, in top-level template code {% include "navigation.html" %} File "/home/bartolomeo/aeh/zjo-pwa/APZ-CeneoScrapper/flask_app/app/templates/navigation.html", line 21, in top-level template code Login File "/usr/local/lib/python3.8/dist-packages/flask_injector/init.py", line 89, in wrapper return injector.call_with_injection(callable=fun, args=args, kwargs=kwargs) File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 999, in call_with_injection dependencies = self.args_to_inject( File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 91, in wrapper return function(*args, **kwargs) File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 1047, in args_to_inject instance: Any = self.get(interface) File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 932, in get binding, binder = self.binder.get_binding(interface) File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 646, in get_binding binding = self.create_binding(interface) File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 560, in create_binding provider = self.provider_for(interface, to) File "/usr/local/lib/python3.8/dist-packages/injector/init.py", line 571, in provider_for raise TypeError('Injecting Any is not supported') TypeError: Injecting Any is not supported
@M1LKYWVYs @Bartolomeo624
Workaround: clear the type hints, which cause the problem, add Flask.url_for.__annotations__ = {}
before app = Flask(...)
I tried Flask.url_for = noninjectable(Flask.url_for, ...)
but it seems not working as expected. I get TypeError: too many positional arguments
@wsz Worked perfectly for this error using apiflask. Thank you!
No update on this issue? =/