Adds Injector support to Flask.

Related tags

Flask flask_injector
Overview

Flask-Injector

Build status Coverage status

Adds Injector support to Flask, this way there's no need to use global Flask objects, which makes testing simpler.

Injector is a dependency-injection framework for Python, inspired by Guice. You can find Injector on PyPI and Injector documentation on Read the Docs.

Flask-Injector is compatible with CPython 3.5+. As of version 0.12.0 it requires Injector version 0.13.2 or greater and Flask 1.0 or greater.

GitHub project page: https://github.com/alecthomas/flask_injector

PyPI package page: https://pypi.org/project/Flask-Injector/

Changelog: https://github.com/alecthomas/flask_injector/blob/master/CHANGELOG.rst

Features

Flask-Injector lets you inject dependencies into:

  • views (functions and class-based)
  • before_request handlers
  • after_request handlers
  • teardown_request handlers
  • template context processors
  • error handlers
  • Jinja environment globals (functions in app.jinja_env.globals)
  • Flask-RESTFul Resource constructors
  • Flask-RestPlus Resource constructors
  • Flask-RESTX Resource constructors

Flask-Injector supports defining types using function annotations (Python 3), see below.

Documentation

As Flask-Injector uses Injector under the hood you should find the Injector documentation, including the Injector API reference, helpful. The Injector README provides a tutorial-level introduction to using Injector.

The Flask-Injector public API consists of the following:

  • FlaskInjector class with the constructor taking the following parameters:
    • app, an instance of`flask.Flask` [mandatory] – the Flask application to be used
    • modules, an iterable of Injector modules [optional] – the Injector modules to be used.
    • injector, an instance of injector.Injector [optional] – an instance of Injector to be used if, for some reason, it's not desirable for FlaskInjector to create a new one. You're likely to not need to use this.
    • request_scope_class, an injector.Scope subclass [optional] – the scope to be used instead of RequestScope. You're likely to need to use this except for testing.
  • RequestScope class – an injector.Scope subclass to be used for storing and reusing request-scoped dependencies
  • request object – to be used as a class decorator or in explicit bind() calls in Injector modules.

Creating an instance of FlaskInjector performs side-effectful configuration of the Flask application passed to it. The following bindings are applied (if you want to modify them you need to do it in one of the modules passed to the FlaskInjector constructor):

  • flask.Flask is bound to the Flask application in the (scope: singleton)
  • flask.Config is bound to the configuration of the Flask application
  • flask.Request is bound to the current Flask request object, equivalent to the thread-local flask.request object (scope: request)

Example application using Flask-Injector

import sqlite3
from flask import Flask, Config
from flask.views import View
from flask_injector import FlaskInjector
from injector import inject

app = Flask(__name__)

# Configure your application by attaching views, handlers, context processors etc.:

@app.route("/bar")
def bar():
    return render("bar.html")


# Route with injection
@app.route("/foo")
def foo(db: sqlite3.Connection):
    users = db.execute('SELECT * FROM users').all()
    return render("foo.html")


# Class-based view with injected constructor
class Waz(View):
    @inject
    def __init__(self, db: sqlite3.Connection):
        self.db = db

    def dispatch_request(self, key):
        users = self.db.execute('SELECT * FROM users WHERE name=?', (key,)).all()
        return 'waz'

app.add_url_rule('/waz/<key>', view_func=Waz.as_view('waz'))


# In the Injector world, all dependency configuration and initialization is
# performed in modules (https://injector.readthedocs.io/en/latest/terminology.html#module).
# The same is true with Flask-Injector. You can see some examples of configuring
# Flask extensions through modules below.

# Accordingly, the next step is to create modules for any objects we want made
# available to the application. Note that in this example we also use the
# Injector to gain access to the `flask.Config`:

def configure(binder):
    binder.bind(
        sqlite3.Connection,
        to=sqlite3.Connection(':memory:'),
        scope=request,
    )

# Initialize Flask-Injector. This needs to be run *after* you attached all
# views, handlers, context processors and template globals.

FlaskInjector(app=app, modules=[configure])

# All that remains is to run the application

app.run()

See example.py for a more complete example, including Flask-SQLAlchemy and Flask-Cache integration.

Supporting Flask Extensions

Typically, Flask extensions are initialized at the global scope using a pattern similar to the following.

app = Flask(__name__)
ext = ExtClass(app)

@app.route(...)
def view():
    # Use ext object here...

As we don't have these globals with Flask-Injector we have to configure the extension the Injector way - through modules. Modules can either be subclasses of injector.Module or a callable taking an injector.Binder instance.

from injector import Module

class MyModule(Module):
    @provider
    @singleton
    def provide_ext(self, app: Flask) -> ExtClass:
        return ExtClass(app)

def main():
    app = Flask(__name__)
    app.config.update(
        EXT_CONFIG_VAR='some_value',
    )

    # attach your views etc. here

    FlaskInjector(app=app, modules=[MyModule])

    app.run()

Make sure to bind extension objects as singletons.

Comments
  • program fall on FlaskInjector(app=app, injector=injector)

    program fall on FlaskInjector(app=app, injector=injector)

    I have Flask app with flask-injector with creat function.

    def create_app(testing: bool = False) -> Flask: app = Flask(__name__) config_app(app, testing) db.init_app(app) migrate.init_app(app, db) router.init_app(app) CORS(app) # Setup injector injector = Injector([AppModule(app.config)]) FlaskInjector(app=app, injector=injector) return app when i start app (flask run) i get error:

    ` Traceback (most recent call last): File "C:\Users\tmv28\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 197, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\Users\tmv28\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 87, in run_code exec(code, run_globals) File "C:\Users\tmv28\Documents\Andrey\test\backend\venv\Scripts\flask.exe_main.py", line 7, in File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask\cli.py", line 967, in main cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask\cli.py", line 586, in main return super(FlaskGroup, self).main(*args, **kwargs) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\click\core.py", line 1059, in main rv = self.invoke(ctx) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\click\core.py", line 1665, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\click\core.py", line 1401, in invoke return ctx.invoke(self.callback, **ctx.params) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\click\core.py", line 767, in invoke return __callback(*args, **kwargs) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\click\decorators.py", line 84, in new_func return ctx.invoke(f, obj, *args, **kwargs) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\click\core.py", line 767, in invoke return __callback(*args, **kwargs) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask\cli.py", line 848, in run_command app = DispatchingApp(info.load_app, use_eager_loading=eager_loading) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask\cli.py", line 305, in init self.load_unlocked() File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask\cli.py", line 330, in load_unlocked self.app = rv = self.loader() File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask\cli.py", line 388, in load_app app = locate_app(self, import_name, name) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask\cli.py", line 240, in locate_app import(module_name) File "C:\Users\tmv28\Documents\Andrey\test\backend\main\server.py", line 4, in app = create_instance() File "C:\Users\tmv28\Documents\Andrey\test\backend\main\apps\server_init.py", line 22, in create_instance return create_app(kwargs.get('testing', False)) File "C:\Users\tmv28\Documents\Andrey\test\backend\main\apps\server\factory.py", line 41, in create_app FlaskInjector(app=app, injector=injector) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask_injector_init.py", line 327, in init process_dict(container, injector) File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask_injector_init.py", line 379, in process_dict elif hasattr(value, 'call'): File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\werkzeug\local.py", line 422, in get obj = instance._get_current_object() File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\werkzeug\local.py", line 544, in _get_current_object return self.__local() # type: ignore File "c:\users\tmv28\documents\andrey\test\backend\venv\lib\site-packages\flask\globals.py", line 38, in _lookup_req_object raise RuntimeError(_request_ctx_err_msg) RuntimeError: Working outside of request context.

    This typically means that you attempted to use functionality that needed an active HTTP request. Consult the documentation on testing for information about how to avoid this problem. ` what did i wrong?

    opened by mrKAndrew 23
  • flask-restful is a hard dependency

    flask-restful is a hard dependency

    I'm using flask-injector==0.10.1 alone with Flask-Restplus However Flask-Restful is a hard dependecy because otherwise the following error will be thrown:

    api_next_1              |   File "/usr/local/lib/python3.6/site-packages/flask_injector.py", line 65, in wrap_fun
    api_next_1              |     return wrap_class_based_view(fun, injector)
    api_next_1              |   File "/usr/local/lib/python3.6/site-packages/flask_injector.py", line 156, in wrap_class_based_view
    api_next_1              |     return wrap_flask_restful_resource(fun, flask_restful_api, injector)
    api_next_1              |   File "/usr/local/lib/python3.6/site-packages/flask_injector.py", line 171, in wrap_flask_restful_resource
    api_next_1              |     from flask_restful.utils import unpack
    api_next_1              | ModuleNotFoundError: No module named 'flask_restful'
    
    opened by yoanisgil 13
  • Cannot inject into teardown_request handler while using request scope

    Cannot inject into teardown_request handler while using request scope

    If I have a request scoped variable, I cannot inject it into a teardown_request handler. If I do, I get the following exception.

    Error on request:
    Traceback (most recent call last):
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/werkzeug/local.py", line 72, in __getattr__
        return self.__storage__[self.__ident_func__()][name]
    KeyError: 139781434668800
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/werkzeug/serving.py", line 304, in run_wsgi
        execute(self.server.app)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/werkzeug/serving.py", line 292, in execute
        application_iter = app(environ, start_response)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__
        return self.wsgi_app(environ, start_response)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/flask/app.py", line 2457, in wsgi_app
        ctx.auto_pop(error)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/flask/ctx.py", line 452, in auto_pop
        self.pop(exc)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/flask/ctx.py", line 415, in pop
        self.app.do_teardown_request(exc)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/flask/app.py", line 2299, in do_teardown_request
        func(exc)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/flask_injector.py", line 89, in wrapper
        return injector.call_with_injection(callable=fun, args=args, kwargs=kwargs)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/injector/__init__.py", line 972, in call_with_injection
        owner_key=self_.__class__ if self_ is not None else callable.__module__,
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/injector/__init__.py", line 96, in wrapper
        return function(*args, **kwargs)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/injector/__init__.py", line 1017, in args_to_inject
        instance = self.get(interface)  # type: Any
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/injector/__init__.py", line 915, in get
        result = scope_instance.get(interface, binding.provider).get(self)
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/flask_injector.py", line 265, in get
        return self._locals.scope[key]
      File "/home/nick/.local/share/virtualenvs/flask_injector_poc-sJYA9nHW/lib/python3.7/site-packages/werkzeug/local.py", line 74, in __getattr__
        raise AttributeError(name)
    AttributeError: scope
    

    After some digging, it seems that this is because Flask executes teardown handlers in the reverse order that they are inserted (see relevant source). Because flask_injector inserts the request scope clean up as a teardown handler, after all others are inserted, flask_injector's handler is run before mine.

    I was able to hack around this by, after setting up my FlaskInjector running app.teardown_request_funcs[None].reverse(). This is not a great solution, IMO. I'm hesitant to submit a PR that just inserts this teardown handler as the first one, as the Flask docs don't seem to guarantee that the handlers are called in reverse order; it seems like an implementation detail.

    What follows is an (admittedly silly) proof of concept that produces the above exception on request.

    import datetime
    import flask
    import flask_injector
    import injector
    
    app = flask.Flask(__name__)
    
    
    @app.route('/')
    def index(time: datetime.datetime):
        return f'The time is {time.isoformat()}'
    
    
    @app.teardown_request
    def teardown_handler(err: Exception, time: datetime.datetime):
        print(f'Tearing down the request from {time.isoformat()}')
    
    
    flask_injector.FlaskInjector(app=app, modules=[
        lambda binder: binder.bind(datetime.datetime, to=datetime.datetime.now(), scope=flask_injector.request)
    ])
    
    if __name__ == '__main__':
        # HACK: works around the bug.
        # app.teardown_request_funcs[None].reverse()
        app.run()
    
    opened by ollien 10
  • injector._BindingNotYetAvailable: name 'Response' is not defined

    injector._BindingNotYetAvailable: name 'Response' is not defined

    Hello, based on code from this post: https://github.com/alecthomas/flask_injector/issues/40 injector throws the above error. My code is almost identical, the only difference is flask_restful instead of flask_restplus:

    from flask import Flask from flask_restful import Api, Resource from flask_injector import FlaskInjector, inject, singleton

    app = Flask(name) app.secret_key = "123" api = Api(app=app)

    class MyConf(): def init(self, val: int): self.val = val

    class MyApi(Resource): @inject def init(self, conf: MyConf, **kwargs): # <- here just added **kwargs to receice the extra passed api parameter self.val = conf.val # Don't know if really needed super().init(**kwargs)

    def get(self, conf: MyConf):
        return {'x': conf.val}, 200
    

    api.add_resource(MyApi, '/myapi')

    def configure(binder): binder.bind( MyConf, to=MyConf(456), scope=singleton ) # No need to bind the resource itself #binder.bind( # MyApi, # to=MyApi(myConf) #)

    FlaskInjector(app=app, modules=[configure])

    app.run(port=555, debug=True)

    Am I doing something wrong here or this is a bug? My setup: Flask==2.0.1 Flask-HTTPAuth==4.4.0 Flask-Injector==0.12.3 Flask-JWT==0.3.2 Flask-RESTful==0.3.9 typing-extensions==3.7.4.3 typing-inspect==0.6.0 injector==0.18.4

    opened by jsr1337 9
  • Doing multiple requests on a flask test client on an injected route fails for all but the first request.

    Doing multiple requests on a flask test client on an injected route fails for all but the first request.

    All but the first call to the test client results in:

        Traceback (most recent call last):
          File "/home/nickh/env/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
                response = self.full_dispatch_request()
          File "/home/nickh/env/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
                rv = self.handle_user_exception(e)
          File "/home/nickh/env/local/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
                reraise(exc_type, exc_value, tb)
          File "/home/nickh/env/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
                rv = self.dispatch_request()
          File "/home/nickh/env/local/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
                return self.view_functions[rule.endpoint](**req.view_args)
          File "/home/nickh/env/local/lib/python2.7/site-packages/flask/views.py", line 83, in view
                self = view.view_class(*class_args, **class_kwargs)
          File "/home/nickh/env/local/lib/python2.7/site-packages/flask_injector.py", line 48, in cls
                current_class, additional_kwargs=kwargs)
          File "/home/nickh/env/local/lib/python2.7/site-packages/injector.py", line 692, in create_object
                instance = cls.__new__(cls)
        TypeError: function.__new__(X): X is not a type object (function)
    

    This looks to be because the flask injector double-wraps the object being made.

    opened by niax 8
  • name 'Response' is not defined

    name 'Response' is not defined

    On Flask 2, I get this error every time I run a query. I have solved the issue only changing the code of Flask-Injector but I am not confident with the impact of the change I have done.

    This error is present when you run the unit test suite. The fix I propose broke the test test_forward_references_work :(.

    Version:

    flask: 2.0.1
    flask-injector: 0.13.0
    flask-restx: 0.5.1
    injector: 0.18.4
    
    127.0.0.1 - - [09/Sep/2021 10:23:38] "GET /swaggerui/favicon-16x16.png HTTP/1.1" 500 -
    Error on request:
    Traceback (most recent call last):
      File "/home/project/.venv/lib/python3.8/site-packages/injector/__init__.py", line 1176, in _infer_injected_bindings
        bindings = get_type_hints(callable, include_extras=True)
      File "/home/project/.venv/lib/python3.8/site-packages/typing_extensions.py", line 1924, in get_type_hints
        hint = typing.get_type_hints(obj, globalns=globalns, localns=localns)
      File "/usr/lib/python3.8/typing.py", line 1264, in get_type_hints
        value = _eval_type(value, globalns, localns)
      File "/usr/lib/python3.8/typing.py", line 270, in _eval_type
        return t._evaluate(globalns, localns)
      File "/usr/lib/python3.8/typing.py", line 518, in _evaluate
        eval(self.__forward_code__, globalns, localns),
      File "<string>", line 1, in <module>
        import importlib.util
    NameError: name 'Response' is not defined
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/home/project/.venv/lib/python3.8/site-packages/werkzeug/serving.py", line 319, in run_wsgi
        execute(self.server.app)
      File "/home/project/.venv/lib/python3.8/site-packages/werkzeug/serving.py", line 308, in execute
        application_iter = app(environ, start_response)
      File "/home/project/.venv/lib/python3.8/site-packages/flask/app.py", line 2088, in __call__
        return self.wsgi_app(environ, start_response)
      File "/home/project/.venv/lib/python3.8/site-packages/flask/app.py", line 2073, in wsgi_app
        response = self.handle_exception(e)
      File "/home/project/.venv/lib/python3.8/site-packages/flask_restx/api.py", line 672, in error_router
        return original_handler(e)
      File "/home/project/.venv/lib/python3.8/site-packages/flask/app.py", line 2070, in wsgi_app
        response = self.full_dispatch_request()
      File "/home/project/.venv/lib/python3.8/site-packages/flask/app.py", line 1515, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/home/project/.venv/lib/python3.8/site-packages/flask_restx/api.py", line 672, in error_router
        return original_handler(e)
      File "/home/project/.venv/lib/python3.8/site-packages/flask/app.py", line 1513, in full_dispatch_request
        rv = self.dispatch_request()
      File "/home/project/.venv/lib/python3.8/site-packages/flask/app.py", line 1499, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
      File "/home/project/.venv/lib/python3.8/site-packages/flask_injector/__init__.py", line 89, in wrapper
        return injector.call_with_injection(callable=fun, args=args, kwargs=kwargs)
      File "/home/project/.venv/lib/python3.8/site-packages/injector/__init__.py", line 1010, in call_with_injection
        bindings = get_bindings(callable)
      File "/home/project/.venv/lib/python3.8/site-packages/injector/__init__.py", line 1163, in get_bindings
        callable, _infer_injected_bindings(callable, only_explicit_bindings=look_for_explicit_bindings)
      File "/home/project/.venv/lib/python3.8/site-packages/injector/__init__.py", line 1178, in _infer_injected_bindings
        raise _BindingNotYetAvailable(e)
    

    I track the root cause in wrap_fun that is supposed to managed this sort of error. On Flask,

      if hasattr(fun, '__call__') and not isinstance(fun, type):
          try:
              type_hints = get_type_hints(fun)
          except (AttributeError, TypeError):
              # Some callables aren't introspectable with get_type_hints,
              # let's assume they don't have anything to inject. The exception
              # types handled here are what I encountered so far.
              # It used to be AttributeError, then https://github.com/python/typing/pull/314
              # changed it to TypeError.
              wrap_it = False
          except NameError:
              wrap_it = True
    

    On Flask, the error is due to the usage of typehint with in flask/scaffold.py

    if t.TYPE_CHECKING:
        from .wrappers import Response
    
    [...]
        def send_static_file(self, filename: str) -> "Response":
    

    The function get_type_hints raise a NameError exception in this context.

    Proposition of fix

    I suppose the existance of NameError has a reason but moving it in Non wrapping condition solve the issue I have. I didn't find the reason of the existence of this condition.

      if hasattr(fun, '__call__') and not isinstance(fun, type):
          try:
              type_hints = get_type_hints(fun)
          except (AttributeError, TypeError, NameError):
              # Some callables aren't introspectable with get_type_hints,
              # let's assume they don't have anything to inject. The exception
              # types handled here are what I encountered so far.
              # It used to be AttributeError, then https://github.com/python/typing/pull/314
              # changed it to TypeError.
              wrap_it = False
    

    More information

    the issue with get_type_hints and Forward Ref

    • https://github.com/python/typing/issues/508
    • https://bugs.python.org/issue43463
    opened by FabienArcellier 7
  • Running In Serverless Lambda Using serverless-wsgi

    Running In Serverless Lambda Using serverless-wsgi

    Hello, Is there a way to use this package without app.run() where serverless doesnt require running the app using the aforementioned command?

    When using this package, for some reason I can't use "contructor injection", nor injector.get(INTERFACE) but this works:

    flask_injector = FlaskInjector(app, modules=modules)
    
    # some code
    # some other code
    # also some other code
    
    flask_injector.get(INTERFACE)
    

    Thanks :D

    opened by AhmedNourJamalElDin 5
  • Error with error handler and typing

    Error with error handler and typing

    Hi! I seem to have a found a bug with the error handler and typing. Consider this code:

    def init_error_handlers(app: Flask) -> None:
        app.register_error_handler(SQLAlchemyError, handle_sqlalchemy_error)
    
    
    def handle_sqlalchemy_error(error: SQLAlchemyError) -> Response:
        logger.error("SQLAlchemy error: %s", error)
        return _create_json_error_response(
            errors.BadRequest.default_message, errors.BadRequest.http_status_code
        )
    

    If I remove the type on the error it works fine, but with the type:

    injector.CallError: Call to handle_sqlalchemy_error(DataError('(psycopg2.DataError) invalid input syntax for type uuid: "61dc1bb7-ed81-448b-88ac-04996a0cff8"\nLINE 3: WHERE organisations.id = \'61dc1bb7-ed81-448b-88ac-04996a0cff...\n                                 ^\n'), error=SQLAlchemyError()) failed: handle_sqlalchemy_error() got multiple values for argument 'error' (injection stack: [])
    

    Full Call stack:

    Traceback (most recent call last):
      File "/Users/******/Core/venv/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
        response = self.full_dispatch_request()
      File "/Users/******/venv/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/Users/******/venv/lib/python3.7/site-packages/flask_cors/extension.py", line 161, in wrapped_function
        return cors_after_request(app.make_response(f(*args, **kwargs)))
      File "/Users/******/venv/lib/python3.7/site-packages/flask/app.py", line 1719, in handle_user_exception
        return handler(e)
      File "/Users/******/venv/lib/python3.7/site-packages/flask_injector.py", line 76, in wrapper
        return injector.call_with_injection(callable=fun, args=args, kwargs=kwargs)
      File "/Users/******/venv/lib/python3.7/site-packages/injector/__init__.py", line 868, in call_with_injection
        reraise(e, CallError(self_, callable, args, dependencies, e, self._stack))
      File "/Users/******/venv/lib/python3.7/site-packages/injector/__init__.py", line 67, in reraise
        raise exception.with_traceback(tb)
      File "/Users/******/venv/lib/python3.7/site-packages/injector/__init__.py", line 866, in call_with_injection
        **dependencies)
    
    opened by Sytten 5
  • Support for flask rebar

    Support for flask rebar

    I was wondering if it would be complex to support flask-rebar (https://github.com/plangrid/flask-rebar). Basically:

    Traceback (most recent call last):
      File "/Users//****//Projects//****//Core/venv/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
        rv = self.dispatch_request()
      File "/Users//****//Projects//****//Core/venv/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "/Users/****/Projects/****/Core/venv/lib/python3.7/site-packages/flask_rebar/rebar.py", line 127, in wrapped
        rv = f(*args, **kwargs)
    TypeError: auth_callback() missing 1 required positional argument: 'service'
    
    opened by Sytten 5
  • Support implicit injections via annotations

    Support implicit injections via annotations

    Injector supports implicit via annotations using use_annotations=True flag (see https://github.com/alecthomas/injector/blob/master/injector_test_py3.py), would be nice to have this in flask_injector.

    opened by roganov 5
  • Simplify

    Simplify

    Would you be interested in the following patch? Unfortunately original flask_injector is not enough for my applications so I had to make some changes and ended up changing quite a lot of code. I'm totally fine with keeping my changes in separate repository but I wouldn't want to fork without trying to have my changes merged first. :)

    Here's what this patch does:

    • simplifies the design, removes FlaskInjector and InjectorView
    • sticks to "native" flask views (function views and Flask class-based views), classed-based views are passed the dependencies as constructor arguments
    • allows injecting into before_request, after_request, request_tearing_down handlers and context processors
    • adds some tests
    opened by jstasiak 5
  • Error while using flask-injector decorator and flask-apispec doc in Flask together.

    Error while using flask-injector decorator and flask-apispec doc in Flask together.

    I have upgraded my packages to: flask-2.2.2 injector-0.20.1 Flask-injector-0.14.1 apispec-6.0.2 flask-apispec-0.11.4

    I'm using Flask-apispec to auto-generate api documentation, and I'm using injector library. both independently works well in my code but when I use them together, somehow @inject decorator doesn't work. and it throws the error missing positional argument. I tried to debug the code, in stack trace, it completely skips the inject decorator.

    Here is a sample code

    import marshmallow as ma
    from flask_apispec import doc, marshal_with, use_kwargs
    from injector import inject
    from flask_injector import FlaskInjector
    from injector import inject, singleton
    
    def configure(binder):
        binder.bind(
            str,
            to="MyCat",
            scope=singleton,
        )
    
    
    class Pet:
        def __init__(self, name, type):
            self.name = name
            self.type = type
    
    
    class PetSchema(ma.Schema):
        name = ma.fields.Str()
        type = ma.fields.Str()
    
    
    
    
    ###
    
    import flask
    import flask.views
    
    from flask_apispec import FlaskApiSpec, MethodResource
    
    app = flask.Flask(__name__)
    docs = FlaskApiSpec(app)
    
    
    @doc(
        tags=['pets'],
        params={'pet_id': {'description': 'the pet name'}},
    )
    class CatResource(MethodResource):
        @inject
        def __init__(self, pet_name: str):
            self.pet_name = pet_name
            super().__init__()
        @marshal_with(PetSchema)
        def get(self, pet_id):
            return Pet(self.pet_name, 'cat')
    
        @marshal_with(PetSchema)
        def put(self, pet_id):
            return Pet('calici', 'cat')
    
    app.add_url_rule('/cat/<pet_id>', view_func=CatResource.as_view('CatResource'))
    
    # registering view
    docs.register(CatResource, endpoint='CatResource')
    FlaskInjector(app=app, modules=[configure])
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    Everything works well if I comment out the "docs.register(CatResource, endpoint='CatResource')"' Note: Everything was working fine before upgrading libraries to the latest

    opened by pratik261199 4
  • chore: add dependency: coverage

    chore: add dependency: coverage

    To eliminate the error as shown below:

    % make test
    nosetests -v flask_injector \
    		--with-coverage --cover-package=flask_injector --cover-html --cover-branches --cover-xml
    nose.plugins.cover: ERROR: Coverage not available: unable to import coverage module
    
    opened by zhangcheng 0
  • Any examples for flask_restful Resources?

    Any examples for flask_restful Resources?

    Hey!

    Im trying to build an app using flask_restful library but I couldn't find an example of flask_injector together with restful.

    Is there any example out there? I tried to replicate the behavior used in flask_restplus implementation but it is not working.

    Thanks in advance

    opened by davidPalechor 1
  • Add conda package reference to README

    Add conda package reference to README

    We recently added a conda wrapper of the PyPI package to conda-forge, installable through

    conda install -c conda-forge flask-injector 
    

    This PR simply adds a reference to that package in the README, in case you want to advertise it directly in this repository as well. If you like, I can also make one maintainer of the conda package (it's mostly a trivial job).

    opened by fuglede 0
  • Using Dynaconf results in TypeError: __name__ must be set to a string object error

    Using Dynaconf results in TypeError: __name__ must be set to a string object error

    Hi

    If I Add FlaskDynaconf(app) before FlaskInjector(app=app, modules=[init_inject]), it'll result in TypeError: __name__ must be set to a string object

    this is the dynaconf project: https://dynaconf.readthedocs.io/en/latest/guides/flask.html

    opened by ahmadalli 7
Owner
Alec Thomas
Alec Thomas
Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

GraphQL Python 1.3k Jan 3, 2023
Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

GraphQL Python 1.2k Feb 17, 2021
A Fast API style support for Flask. Gives you MyPy types with the flexibility of flask

Flask-Fastx Flask-Fastx is a Fast API style support for Flask. It Gives you MyPy types with the flexibility of flask. Compatibility Flask-Fastx requir

Tactful.ai 18 Nov 26, 2022
flask-apispec MIT flask-apispec (🥉24 · ⭐ 520) - Build and document REST APIs with Flask and apispec. MIT

flask-apispec flask-apispec is a lightweight tool for building REST APIs in Flask. flask-apispec uses webargs for request parsing, marshmallow for res

Joshua Carp 617 Dec 30, 2022
Cross Origin Resource Sharing ( CORS ) support for Flask

Flask-CORS A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible. This package has a simple philosoph

Cory Dolphin 803 Jan 1, 2023
MongoEngine flask extension with WTF model forms support

Flask-MongoEngine Info: MongoEngine for Flask web applications. Repository: https://github.com/MongoEngine/flask-mongoengine About Flask-MongoEngine i

MongoEngine 815 Jan 3, 2023
i18n and l10n support for Flask based on Babel and pytz

Flask Babel Implements i18n and l10n support for Flask. This is based on the Python babel module as well as pytz both of which are installed automatic

null 397 Dec 15, 2022
Pagination support for flask

flask-paginate Pagination support for flask framework (study from will_paginate). It supports several css frameworks. It requires Python2.6+ as string

Lix Xu 264 Nov 7, 2022
Pagination support for flask

flask-paginate Pagination support for flask framework (study from will_paginate). It supports several css frameworks. It requires Python2.6+ as string

Lix Xu 223 Feb 17, 2021
WebSocket support for Flask

flask-sock WebSocket support for Flask Installation pip install flask-sock Example from flask import Flask, render_template from flask_sock import Soc

Miguel Grinberg 165 Dec 27, 2022
An extension to add support of Plugin in Flask.

An extension to add support of Plugin in Flask.

Doge Gui 31 May 19, 2022
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

Max Countryman 310 Dec 14, 2022
Flask-Rebar combines flask, marshmallow, and swagger for robust REST services.

Flask-Rebar Flask-Rebar combines flask, marshmallow, and swagger for robust REST services. Features Request and Response Validation - Flask-Rebar reli

PlanGrid 223 Dec 19, 2022
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

Max Countryman 282 Feb 11, 2021
Flask-Starter is a boilerplate starter template designed to help you quickstart your Flask web application development.

Flask-Starter Flask-Starter is a boilerplate starter template designed to help you quickstart your Flask web application development. It has all the r

Kundan Singh 259 Dec 26, 2022
Brandnew-flask is a CLI tool used to generate a powerful and mordern flask-app that supports the production environment.

Brandnew-flask is still in the initial stage and needs to be updated and improved continuously. Everyone is welcome to maintain and improve this CLI.

brandonye 4 Jul 17, 2022
Flask Project Template A full feature Flask project template.

Flask Project Template A full feature Flask project template. See also Python-Project-Template for a lean, low dependency Python app. HOW TO USE THIS

Bruno Rocha 96 Dec 23, 2022
Flask-app scaffold, generate flask restful backend

Flask-app scaffold, generate flask restful backend

jacksmile 1 Nov 24, 2021
Flask pre-setup architecture. This can be used in any flask project for a faster and better project code structure.

Flask pre-setup architecture. This can be used in any flask project for a faster and better project code structure. All the required libraries are already installed easily to use in any big project.

Ajay kumar sharma 5 Jun 14, 2022