Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange exception when open swggaer doc -> TypeError('Injecting Any is not supported') #78

Open
M1LKYWVYs opened this issue Mar 1, 2023 · 6 comments

Comments

@M1LKYWVYs
Copy link

M1LKYWVYs commented Mar 1, 2023

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.

@jstasiak
Copy link
Collaborator

jstasiak commented Apr 3, 2023

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.

@Bartolomeo624
Copy link

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

@wsz
Copy link

wsz commented May 18, 2023

@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

@robob4him
Copy link

@wsz Worked perfectly for this error using apiflask. Thank you!

@aderbas
Copy link

aderbas commented May 7, 2024

No update on this issue? =/

@Kraziyi
Copy link

Kraziyi commented Oct 3, 2024

Any updates on this issue? Meet the same issue: TypeError: Injecting Any is not supported when trying to render_template even though I did not add @inject annotation on that blueprint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants