Example #1
11
def test_assisted_building_is_supported():
    class Fetcher:
        def fetch(self, user_id):
            assert user_id == 333
            return {'name': 'John'}

    class Processor:
        @noninjectable('provider_id')
        @inject
        @noninjectable('user_id')
        def __init__(self, fetcher: Fetcher, user_id: int, provider_id: str):
            assert provider_id == 'not injected'
            data = fetcher.fetch(user_id)
            self.name = data['name']

    def configure(binder):
        binder.bind(int, to=897)
        binder.bind(str, to='injected')

    injector = Injector(configure)
    processor_builder = injector.get(AssistedBuilder[Processor])

    with pytest.raises(CallError):
        processor_builder.build()

    processor = processor_builder.build(user_id=333, provider_id='not injected')
    assert processor.name == 'John'
Example #2
2
def test_avoid_circular_dependency_with_method_injection():
    class Interface(object):
        pass

    class A(object):
        @inject(i=Interface)
        def __init__(self, i):
            self.i = i

    # Even though A needs B (via Interface) and B.method() needs A, they are
    # resolved at different times, avoiding circular dependencies.
    class B(object):
        @inject(a=A)
        def method(self, a):
            self.a = a

    def configure(binder):
        binder.bind(Interface, to=B)
        binder.bind(A)
        binder.bind(B)

    injector = Injector(configure)
    a = injector.get(A)
    assert (isinstance(a.i, B))
    b = injector.get(B)
    b.method()
    assert (isinstance(b.a, A))
	def parse(self,response):
		if self.crawling=="Streaming":
			sys.path.insert(0,"/media/shrinivaasanka/0fc4d8a2-1c74-42b8-8099-9ef78d8c8ea2/home/kashrinivaasan/KrishnaiResearch_OpenSource/GitHub/asfer-github-code/python-src/backend")
			import Abstract_DBBackend
			import MySQL_DBBackend
			import MySQL_Configuration
			import MongoDB_DBBackend
			import MongoDB_Configuration
			from pymongo.collection import Collection
			mysqldbobj=MySQL_DBBackend.MySQL_DBBackend()
			mysqlconfigobj=MySQL_Configuration.MySQL_Configuration()
			injector=Injector([mysqldbobj,mysqlconfigobj])
			handler=injector.get(Abstract_DBBackend.Abstract_DBBackend)
			#handler.execute_query("CREATE TABLE asfer_webspider(Description varchar(100))")
			select = Selector(response)
			links_list = select.xpath('//h3/a/@href').extract()
			links_list2 = [re.search('q=(.*)&sa',n).group(1) for n in links_list]
			desc_list=select.xpath('//h3/a/text()').extract()
			items=[]
			for desc in desc_list:
				item=WebSpiderItem()
				item['desc'] = desc
				items.append(item)
				self.output.write(desc)
				self.output.write("\n")
				handler.execute_query("INSERT INTO asfer_webspider(Description) VALUES(\""+desc+"\")","MySQL")
			handler.execute_query("SELECT * FROM asfer_webspider","MySQL")
			return items
		if self.crawling=="HTML":
			bsoup=BeautifulSoup(response.body)
			for script in bsoup(["script","style"]):
				script.extract()
			self.output.write(bsoup.get_text().encode("utf-8"))
Example #4
0
def main():
    app = Flask(__name__)
    app.config.update(
        DB_CONNECTION_STRING=':memory:',
        CACHE_TYPE='simple',
        SQLALCHEMY_DATABASE_URI='sqlite://',
    )
    app.debug = True

    injector = Injector([AppModule(app)])
    configure_views(app=app, cached=injector.get(Cache).cached)

    FlaskInjector(app=app, injector=injector)

    client = app.test_client()

    response = client.get('/')
    print('%s\n%s%s' % (response.status, response.headers, response.data))
    response = client.post('/', data={'key': 'foo', 'value': 'bar'})
    print('%s\n%s%s' % (response.status, response.headers, response.data))
    response = client.get('/')
    print('%s\n%s%s' % (response.status, response.headers, response.data))
    response = client.get('/hello')
    print('%s\n%s%s' % (response.status, response.headers, response.data))
    response = client.delete('/hello')
    print('%s\n%s%s' % (response.status, response.headers, response.data))
    response = client.get('/')
    print('%s\n%s%s' % (response.status, response.headers, response.data))
    response = client.get('/hello')
    print('%s\n%s%s' % (response.status, response.headers, response.data))
    response = client.delete('/hello')
    print('%s\n%s%s' % (response.status, response.headers, response.data))
Example #5
0
def test_explicitly_passed_parameters_override_injectable_values():
    # The class needs to be defined globally for the 'X' forward reference to be able to be resolved.
    global X

    # We test a method on top of regular function to exercise the code path that's
    # responsible for handling methods.
    class X:
        @inject
        def method(self, s: str) -> str:
            return s

        @inject
        def method_typed_self(self: 'X', s: str) -> str:
            return s

    @inject
    def function(s: str) -> str:
        return s

    injection_counter = 0

    def provide_str() -> str:
        nonlocal injection_counter
        injection_counter += 1
        return 'injected string'

    def configure(binder: Binder) -> None:
        binder.bind(str, to=provide_str)

    injector = Injector([configure])
    x = X()

    try:
        assert injection_counter == 0

        assert injector.call_with_injection(x.method) == 'injected string'
        assert injection_counter == 1
        assert injector.call_with_injection(x.method_typed_self) == 'injected string'
        assert injection_counter == 2
        assert injector.call_with_injection(function) == 'injected string'
        assert injection_counter == 3

        assert injector.call_with_injection(x.method, args=('passed string',)) == 'passed string'
        assert injection_counter == 3
        assert injector.call_with_injection(x.method_typed_self, args=('passed string',)) == 'passed string'
        assert injection_counter == 3
        assert injector.call_with_injection(function, args=('passed string',)) == 'passed string'
        assert injection_counter == 3

        assert injector.call_with_injection(x.method, kwargs={'s': 'passed string'}) == 'passed string'
        assert injection_counter == 3
        assert (
            injector.call_with_injection(x.method_typed_self, kwargs={'s': 'passed string'})
            == 'passed string'
        )
        assert injection_counter == 3
        assert injector.call_with_injection(function, kwargs={'s': 'passed string'}) == 'passed string'
        assert injection_counter == 3
    finally:
        del X
Example #6
0
def test_things_dont_break_in_presence_of_args_or_kwargs():
    class A:
        @inject
        def __init__(self, s: str, *args: int, **kwargs: str):
            assert not args
            assert not kwargs

    injector = Injector()

    # The following line used to fail with something like this:
    # Traceback (most recent call last):
    #   File "/ve/injector/injector_test_py3.py", line 192,
    #     in test_things_dont_break_in_presence_of_args_or_kwargs
    #     injector.get(A)
    #   File "/ve/injector/injector.py", line 707, in get
    #     result = scope_instance.get(key, binding.provider).get(self)
    #   File "/ve/injector/injector.py", line 142, in get
    #     return injector.create_object(self._cls)
    #   File "/ve/injector/injector.py", line 744, in create_object
    #     init(instance, **additional_kwargs)
    #   File "/ve/injector/injector.py", line 1082, in inject
    #     kwargs=kwargs
    #   File "/ve/injector/injector.py", line 851, in call_with_injection
    #     **dependencies)
    #   File "/ve/injector/injector_test_py3.py", line 189, in __init__
    #     assert not kwargs
    #   AssertionError: assert not {'args': 0, 'kwargs': ''}
    injector.get(A)
Example #7
0
def test_dependency_cycle_can_be_worked_broken_by_assisted_building():
    class Interface:
        pass

    class A:
        @inject
        def __init__(self, i: Interface):
            self.i = i

    class B:
        @inject
        def __init__(self, a_builder: AssistedBuilder[A]):
            self.a = a_builder.build(i=self)

    def configure(binder):
        binder.bind(Interface, to=B)
        binder.bind(A)

    injector = Injector(configure)

    # Previously it'd detect a circular dependency here:
    # 1. Constructing A requires Interface (bound to B)
    # 2. Constructing B requires assisted build of A
    # 3. Constructing A triggers circular dependency check
    assert isinstance(injector.get(A), A)
Example #8
0
	def __init__(self, options):
		packageName=options.package

		assert packageName, "需要使用 -p 來指定要載入的編碼法(輸入法或描繪法)模組名稱"

		package = __import__(packageName, fromlist=["coding"])

		output_format=options.output_format
		quiet=options.quiet


		writer = self.computeWriter(package.codingType, quiet, output_format)

		def configure(binder):
			binder.bind(CodingConfig, to=CodingConfig(package))
			binder.bind(Package, to=package)
			binder.bind(Writer, to=writer)

		injector = Injector([configure, PackageModule()])
		structureManager = injector.get(StructureManager)

		injector = Injector([configure, PackageModule(), ManagerModule(structureManager)])
		mainManager=injector.get(MainManager)
		mainManager.compute()
		mainManager.write()
Example #9
0
def test_bind_interface_of_list_of_types():
    def configure(binder):
        binder.multibind([int], to=[1, 2, 3])
        binder.multibind([int], to=[4, 5, 6])

    injector = Injector(configure)
    assert injector.get([int]) == [1, 2, 3, 4, 5, 6]
Example #10
0
def prepare_nested_injectors():
    def configure(binder):
        binder.bind(str, to='asd')

    parent = Injector(configure)
    child = parent.create_child_injector()
    return parent, child
Example #11
0
def test_threadlocal():
    @threadlocal
    class A(object):
        def __init__(self):
            pass

    def configure(binder):
        binder.bind(A)

    injector = Injector(configure)
    a1 = injector.get(A)
    a2 = injector.get(A)

    assert (a1 is a2)

    a3 = [None]
    ready = threading.Event()

    def inject_a3():
        a3[0] = injector.get(A)
        ready.set()

    threading.Thread(target=inject_a3).start()
    ready.wait(1.0)

    assert (a2 is not a3[0] and a3[0] is not None)
Example #12
0
def test_auto_bind():

    class A(object):
        pass

    injector = Injector()
    assert (isinstance(injector.get(A), A))
Example #13
0
def test_call_to_method_containing_noninjectable_and_unsatisfied_dependencies_raises_the_right_error():
    class A(object):
        @inject(something=str)
        def fun(self, something, something_different):
            pass

    injector = Injector()
    a = injector.get(A)
    try:
        a.fun()
    except CallError as ce:
        assert (ce.args[0] == a)

        # We cannot really check for function identity here... Error is raised after calling
        # original function but from outside we have access to function already decorated
        function = A.fun

        # Python 3 compatibility
        try:
            function = function.__func__
        except AttributeError:
            pass
        assert (ce.args[1].__name__ == function.__name__)

        assert (ce.args[2] == ())
        assert (ce.args[3] == {'something': str()})
Example #14
0
class TestBuilder(object):
    """
    """

    def setup_method(self, method):
        self.injector = Injector([SandboxModuleTest()])
        self.dispatcher = self.injector.get(Dispatcher)
        self.builder = self.injector.get(Builder)
        self._composer = self.injector.get(Composer)

        self._build = Mock()
        self.builder.build = self._build
        self.builder._composer = self._composer

    def test_build_not_sandbox_image(self):
        images = ['external1', 'sandbox/internal1']
        calls = ['internal1:master']

        options = {
            '<flavour>': 'with_external_component',
            '--force': True
        }

        self.dispatcher.build_all(options)
        for call in calls:
            self._build.assert_any_call(call)

        assert mock.call('external1') not in self._build.mock_calls
Example #15
0
def test_newtype_integration_works():
    UserID = NewType('UserID', int)

    def configure(binder):
        binder.bind(UserID, to=123)

    injector = Injector([configure])
    assert injector.get(UserID) == 123
Example #16
0
def test_call_to_method_with_legitimate_call_error_raises_type_error():
    class A(object):
        def __init__(self):
            max()

    injector = Injector()
    with pytest.raises(TypeError):
        injector.get(A)
Example #17
0
def test_implicit_injection_fails_when_annotations_are_missing():
    class A(object):
        def __init__(self, n):
            self.n = n

    injector = Injector()
    with pytest.raises(CallError):
        injector.get(A)
Example #18
0
def test_module_provides():
    class MyModule(Module):
        @provides(str, annotation="name")
        def provide_name(self):
            return "Bob"

    module = MyModule()
    injector = Injector(module)
    assert injector.get(str, annotation="name") == "Bob"
Example #19
0
def test_module_provides():
    class MyModule(Module):
        @provides(str)
        def provide_name(self):
            return 'Bob'

    module = MyModule()
    injector = Injector(module)
    assert injector.get(str) == 'Bob'
Example #20
0
    def test_mutating_dict_while_iterating_it_bug(self):
        bindings = dict(('_' + str(i), str) for i in range(1000))

        @inject(**bindings)
        class X(object):
            pass

        injector = Injector()
        injector.get(X)
Example #21
0
def test_inject_with_missing_dependency():
    A, _ = prepare_basic_injection()

    def configure(binder):
        binder.bind(A)

    injector = Injector(configure, auto_bind=False)
    with pytest.raises(UnsatisfiedRequirement):
        injector.get(A)
Example #22
0
def test_module_provides():
    class MyModule(Module):
        @provides(str, annotation='name')
        def provide_name(self):
            return 'Bob'

    module = MyModule()
    injector = Injector(module)
    assert (injector.get(str, annotation='name') == 'Bob')
Example #23
0
def test_module_class_gets_instantiated():
    name = 'Meg'

    class MyModule(Module):
        def configure(self, binder):
            binder.bind(str, to=name)

    injector = Injector(MyModule)
    assert (injector.get(str) == name)
Example #24
0
def test_binder_provider_for_type_with_metaclass():
    # use a metaclass cross python2/3 way
    # otherwise should be:
    # class A(object, metaclass=abc.ABCMeta):
    #    passa
    A = abc.ABCMeta('A', (object, ), {})

    binder = Injector().binder
    assert (isinstance(binder.provider_for(A, None).get(), A))
Example #25
0
def test_assisted_builder_works_when_injected():
    class X:
        @inject
        def __init__(self, builder: AssistedBuilder[NeedsAssistance]):
            self.obj = builder.build(b=234)

    injector = Injector()
    x = injector.get(X)
    assert (x.obj.a, x.obj.b) == (str(), 234)
Example #26
0
def test_assisted_builder_works_when_injected():
    class X(object):
        @inject(builder=AssistedBuilder(NeedsAssistance))
        def __init__(self, builder):
            self.obj = builder.build(b=234)

    injector = Injector()
    x = injector.get(X)
    assert ((x.obj.a, x.obj.b) == (str(), 234))
Example #27
0
def test_assisted_builder_injection_is_safe_to_use_with_multiple_injectors():
    class X(object):
        @inject(builder=AssistedBuilder(NeedsAssistance))
        def y(self, builder):
            return builder

    i1, i2 = Injector(), Injector()
    b1 = i1.get(X).y()
    b2 = i2.get(X).y()
    assert ((b1.injector, b2.injector) == (i1, i2))
Example #28
0
def test_get_default_injected_instances():
    A, B = prepare_basic_injection()

    def configure(binder):
        binder.bind(A)
        binder.bind(B)

    injector = Injector(configure)
    assert (injector.get(Injector) is injector)
    assert (injector.get(Binder) is injector.binder)
Example #29
0
def app_and_injector(config_file, *ext_mods):
  parent  = Injector([AppModule(config_file)])
  app     = parent.get(Flask)
  modules = [
    DbModule(app),
    ApiV1Module(app),
  ]

  i = FlaskInjector(app, modules + list(ext_mods), parent)
  return i.app, i.injector
Example #30
0
def test_assisted_builder_uses_bindings():
    Interface = Key('Interface')

    def configure(binder):
        binder.bind(Interface, to=NeedsAssistance)

    injector = Injector(configure)
    builder = injector.get(AssistedBuilder(Interface))
    x = builder.build(b=333)
    assert ((type(x), x.b) == (NeedsAssistance, 333))
Example #31
0
    @singleton
    @provider
    def provide_business_logic(self, api: Api) -> BusinessLogic:
        return BusinessLogic(api=api)

    @singleton
    @provider
    def provide_api(self) -> Api:
        # there is no complex logic in our case,
        # but you can use this method to hide the complexity of initial
        configuration
        # e.g. when instantiating a particular DB connector.
        return Api()


class TestAppModule(Module):
    @singleton
    @provider
    def provide_api(self) -> Api:
        return TestApi()


if __name__ == '__main__':
    real_injector = Injector(AppModule())
    test_injector = Injector([AppModule(), TestAppModule()])

    real_logic = real_injector.get(BusinessLogic)
    real_logic.do_stuff()

    test_logic = test_injector.get(BusinessLogic)
    test_logic.do_stuff()
Example #32
0
def test_implicit_injection_for_python3():
    injector = Injector()
    c = injector.get(ImplicitC)
    assert isinstance(c, ImplicitC)
    assert isinstance(c.b, ImplicitB)
    assert isinstance(c.b.a, ImplicitA)
Example #33
0
def inject_packet_logger(pid: int):
    injector = Injector()
    injector.load_from_pid(pid)
    injector.inject_dll(get_packet_logger_path(pid))
Example #34
0
def test_auto_bind():
    class A:
        pass

    injector = Injector()
    assert isinstance(injector.get(A), A)
Example #35
0
    def __init__(
        self,
        app: flask.Flask,
        modules: Iterable[_ModuleT] = [],
        injector: Injector = None,
        request_scope_class: type = RequestScope,
    ) -> None:
        """Initializes Injector for the application.

        .. note::

            Needs to be called *after* all views, signal handlers, template globals
            and context processors are registered.

        :param app: Application to configure
        :param modules: Configuration for newly created :class:`injector.Injector`
        :param injector: Injector to initialize app with, if not provided
            a new instance will be created.
        :type app: :class:`flask.Flask`
        :type modules: Iterable of configuration modules
        :rtype: :class:`injector.Injector`
        """
        if not injector:
            injector = Injector()

        modules = list(modules)
        modules.insert(
            0, FlaskModule(app=app, request_scope_class=request_scope_class))
        for module in modules:
            injector.binder.install(module)

        for container in (
                app.view_functions,
                app.before_request_funcs,
                app.after_request_funcs,
                app.teardown_request_funcs,
                app.template_context_processors,
                app.jinja_env.globals,
                app.error_handler_spec,
        ):
            process_dict(container, injector)

        process_list(app.before_first_request_funcs, injector)

        # This is to make sure that mypy sees a non-nullable variable
        # in the closures below, otherwise it'd complain that injector
        # union may not have get attribute
        injector_not_null = injector

        def reset_request_scope_before(*args: Any, **kwargs: Any) -> None:
            injector_not_null.get(request_scope_class).prepare()

        def reset_request_scope_after(*args: Any, **kwargs: Any) -> None:
            injector_not_null.get(request_scope_class).cleanup()

        app.before_request_funcs.setdefault(None, []).insert(
            0, reset_request_scope_before)
        # We're accessing Flask internals here as the app.teardown_request decorator appends to a list of
        # handlers but Flask itself reverses the list when it executes them. To allow injecting request-scoped
        # dependencies into teardown_request handlers we need to run our teardown_request handler after them.
        # Also see https://github.com/alecthomas/flask_injector/issues/42 where it was reported.
        app.teardown_request_funcs.setdefault(None, []).insert(
            0, reset_request_scope_after)

        self.injector = injector_not_null
        self.app = app
Example #36
0
def test_binder_provider_for_method_with_instance():
    injector = Injector()
    binder = injector.binder
    provider = binder.provider_for(int, to=1)
    assert type(provider) is InstanceProvider
    assert provider.get(injector) == 1
Example #37
0
def _get_storage() -> Storage:
    injector = Injector(modules=[ApplicationModule])
    storage = injector.get(Storage)
    click.echo(storage.config)
    return storage
Example #38
0
from marketing_api.app import createApp
from marketing_api import startup
from marketing_api.db.model import Database

logging.basicConfig()

logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
logging.getLogger().setLevel(logging.INFO)

parser = argparse.ArgumentParser(description='Start Marketing backend server')
parser.add_argument("--dbhost", help="database host to connect", default='db')
parser.add_argument("--dbport",
                    type=int,
                    help="database port to connect",
                    default=3306)

args = parser.parse_args()

if __name__ == '__main__':
    app, api, db = createApp(args.dbhost, args.dbport)

    def databaseProvider(binder: Binder):
        binder.bind(Database, to=db, scope=singleton)

    injector = Injector([databaseProvider])

    startup.setup(injector, api, db)

    app.run(debug=True, use_reloader=False, port=5000, host="0.0.0.0")
Example #39
0
        baseline_accuracies = {
            100: 0.6210,
            200: 0.6173,
            1000: 0.7945,
            10000: 0.84692,
            20000: 0.8484,
        }

        # Start the simulation.
        self._s.simulate(
            agents,
            baseline_accuracy=baseline_accuracies[num_words],
            init_train_data_portion=init_train_data_portion,
            pm_test_sets=test_sets,
            accuracy_plot_wait_s=math.inf,
            train_size=train_size,
        )


# Run with `bokeh serve PATH`.
if __name__.startswith('bk_script_'):
    # Set up the data, model, and incentive mechanism.
    inj = Injector([
        DefaultCollaborativeTrainerModule,
        ImdbDataModule(num_words=num_words),
        LoggingModule,
        PerceptronModule,
        PredictionMarketImModule,
    ])
    inj.get(Runner).run()
Example #40
0
import uuid
from abc import ABC

from injector import InstanceProvider, Module, provider, Injector, ClassProvider, SingletonScope

from injector import inject

from inject_.domain import UserManager, UserModule, UserAttributeModule

injector = Injector([UserModule, UserAttributeModule])

user_manager_1 = injector.get(UserManager)
print(user_manager_1.user.id)

user_manager_2 = injector.get(UserManager)
print(user_manager_2.user.id)

user_manager_2.risk_it()
    def provide_ledstrip(self, configuration: Configuration) -> LedstripBase:
        if configuration.ledstrip_type == LedstripType.HARDWARE:
            from ledstrip import Ledstrip
            return Ledstrip(configuration.pixel_count)
        elif configuration.ledstrip_type == LedstripType.GIF:
            from gifwriterledstrip import GifWriterLedstrip
            return GifWriterLedstrip(configuration.pixel_count,
                                     configuration.update_rate_in_seconds)

    @singleton
    @provider
    def provide_animation_runner(
            self, configuration: Configuration) -> AnimationRunnerBase:
        if configuration.animation_runner_type == RunnerType.THREAD:
            return ThreadAnimationRunner(configuration.update_rate_in_seconds)
        elif configuration.animation_runner_type == RunnerType.BASE:
            return AnimationRunnerBase()
        elif configuration.animation_runner_type == RunnerType.COUNTING:
            return CountingAnimationRunner(configuration.animation_iterations)

    @singleton
    @provider
    def provide_flask(self, configuration: Configuration) -> Flask:
        return Flask(__name__, static_folder="static")


if os.getenv("LOCATION") == "local":
    injector = Injector([configure_for_test, LedstripModule()])
else:
    injector = Injector([configure_for_raspi, LedstripModule()])
Example #42
0
def test_binder_provider_for_method_with_class():
    injector = Injector()
    binder = injector.binder
    provider = binder.provider_for(int)
    assert type(provider) is ClassProvider
    assert provider.get(injector) == 0
Example #43
0
def register_extensions(app):
    db.init_app(app)
    Migrate(app, db)

    injector = Injector([PaymentManagerModule(app)])
    FlaskInjector(app=app, injector=injector)
Example #44
0
 def get(self, injector: Injector) -> List[T]:
     return [injector.create_object(self._cls)]
Example #45
0
def get_injector() -> Injector:
    global _injector
    if _injector is None:
        _injector = Injector([InjectorConfiguration])
    return _injector
Example #46
0
from injector import Injector

from .db import PersistenceModule
from .subscription.plan import SubscriptionPlanModule

register: Injector = Injector([PersistenceModule, SubscriptionPlanModule])

__all__ = ['register']
Example #47
0
 def setUp(self):
     
     injector = Injector([ProcessorsModule()])
     self.img_to_text_service = injector.get(ImageToTextService)  
Example #48
0
def test_assisted_builder_works_when_got_directly_from_injector():
    injector = Injector()
    builder = injector.get(AssistedBuilder[NeedsAssistance])
    obj = builder.build(b=123)
    assert (obj.a, obj.b) == (str(), 123)
Example #49
0
def test_explicitly_passed_parameters_override_injectable_values():
    # The class needs to be defined globally for the 'X' forward reference to be able to be resolved.
    global X

    # We test a method on top of regular function to exercise the code path that's
    # responsible for handling methods.
    class X:
        @inject
        def method(self, s: str) -> str:
            return s

        @inject
        def method_typed_self(self: 'X', s: str) -> str:
            return s

    @inject
    def function(s: str) -> str:
        return s

    injection_counter = 0

    def provide_str() -> str:
        nonlocal injection_counter
        injection_counter += 1
        return 'injected string'

    def configure(binder: Binder) -> None:
        binder.bind(str, to=provide_str)

    injector = Injector([configure])
    x = X()

    try:
        assert injection_counter == 0

        assert injector.call_with_injection(x.method) == 'injected string'
        assert injection_counter == 1
        assert injector.call_with_injection(x.method_typed_self) == 'injected string'
        assert injection_counter == 2
        assert injector.call_with_injection(function) == 'injected string'
        assert injection_counter == 3

        assert injector.call_with_injection(x.method, args=('passed string',)) == 'passed string'
        assert injection_counter == 3
        assert injector.call_with_injection(x.method_typed_self, args=('passed string',)) == 'passed string'
        assert injection_counter == 3
        assert injector.call_with_injection(function, args=('passed string',)) == 'passed string'
        assert injection_counter == 3

        assert injector.call_with_injection(x.method, kwargs={'s': 'passed string'}) == 'passed string'
        assert injection_counter == 3
        assert (
            injector.call_with_injection(x.method_typed_self, kwargs={'s': 'passed string'})
            == 'passed string'
        )
        assert injection_counter == 3
        assert injector.call_with_injection(function, kwargs={'s': 'passed string'}) == 'passed string'
        assert injection_counter == 3
    finally:
        del X
 def setUp(self):
     configure_logging(logging.INFO)
     injector = Injector([DefaultModule])
     self.asset_service = injector.get(AssetService)
     self.service = injector.get(FactorService)
Example #51
0
def test_optionals_are_ignored_for_now():
    @inject
    def fun(s: str = None):
        return s

    assert Injector().call_with_injection(fun) == ''
Example #52
0
def setup_injector() -> Injector:
    return Injector(setup_di)
    def __init__(
        self,
        app: flask.Flask,
        modules: Iterable[_ModuleT] = [],
        injector: Injector = None,
        request_scope_class: type = RequestScope,
    ) -> None:
        """Initializes Injector for the application.

        .. note::

            Needs to be called *after* all views, signal handlers, template globals
            and context processors are registered.

        :param app: Application to configure
        :param modules: Configuration for newly created :class:`injector.Injector`
        :param injector: Injector to initialize app with, if not provided
            a new instance will be created.
        :type app: :class:`flask.Flask`
        :type modules: Iterable of configuration modules
        :rtype: :class:`injector.Injector`
        """
        if not injector:
            injector = Injector()

        modules = list(modules)
        modules.insert(0, FlaskModule(app=app, request_scope_class=request_scope_class))
        for module in modules:
            injector.binder.install(module)

        for container in (
            app.view_functions,
            app.before_request_funcs,
            app.after_request_funcs,
            app.teardown_request_funcs,
            app.template_context_processors,
            app.jinja_env.globals,
            app.error_handler_spec,
        ):
            process_dict(container, injector)

        process_list(app.before_first_request_funcs, injector)

        # This is to make sure that mypy sees a non-nullable variable
        # in the closures below, otherwise it'd complain that injector
        # union may not have get attribute
        injector_not_null = injector

        def reset_request_scope_before(*args: Any, **kwargs: Any) -> None:
            injector_not_null.get(request_scope_class).prepare()

        def global_reset_request_scope_after(*args: Any, **kwargs: Any) -> None:
            blueprint = flask.request.blueprint
            # If current blueprint has teardown_request_funcs associated with it we know there may be
            # a some teardown request handlers we need to inject into, so we can't reset the scope just yet.
            # We'll leave it to blueprint_reset_request_scope_after to do the job which we know will run
            # later and we know it'll run after any teardown_request handlers we may want to inject into.
            if blueprint is None or blueprint not in app.teardown_request_funcs:
                injector_not_null.get(request_scope_class).cleanup()

        def blueprint_reset_request_scope_after(*args: Any, **kwargs: Any) -> None:
            # If we got here we truly know this is the last teardown handler, which means we can reset the
            # scope unconditionally.
            injector_not_null.get(request_scope_class).cleanup()

        app.before_request_funcs.setdefault(None, []).insert(0, reset_request_scope_before)
        # We're accessing Flask internals here as the app.teardown_request decorator appends to a list of
        # handlers but Flask itself reverses the list when it executes them. To allow injecting request-scoped
        # dependencies into teardown_request handlers we need to run our teardown_request handler after them.
        # Also see https://github.com/alecthomas/flask_injector/issues/42 where it was reported.
        # Secondly, we need to handle blueprints. Flask first executes non-blueprint teardown handlers in
        # reverse order and only then executes blueprint-associated teardown handlers in reverse order,
        # which means we can't just set on non-blueprint teardown handler, but we need to set both.
        # In non-blueprint teardown handler we check if a blueprint handler will run – if so, we do nothing
        # there and leave it to the blueprint teardown handler.
        #
        # We need the None key to be present in the dictionary so that the dictionary iteration always yields
        # None as well. We *always* have to set the global teardown request.
        app.teardown_request_funcs.setdefault(None, []).insert(0, global_reset_request_scope_after)
        for bp, functions in app.teardown_request_funcs.items():
            if bp is not None:
                functions.insert(0, blueprint_reset_request_scope_after)

        self.injector = injector_not_null
        self.app = app
 def setUp(self):
     self._redis: StrictRedis = Mock(StrictRedis)
     module = TestCaseModule(self._redis)
     injector = Injector(modules=[module])
     self._redis_repository: RedisRepository = injector.get(RedisRepository)
Example #55
0
def test_providerof_cannot_be_bound():
    def configure(binder):
        binder.bind(ProviderOf[int], to=InstanceProvider(None))

    with pytest.raises(Exception):
        Injector(configure)
        self._db = db

    def get(self):
        cursor = self._db.cursor()
        cursor.execute('SELECT key, value FROM data ORDER by key')
        return cursor.fetchall()


def configure_for_testing(binder):
    configuration = {'db_connection_string': ':memory:'}
    binder.bind(Configuration, to=configuration, scope=singleton)


class DatabaseModule(Module):
    @singleton
    @provider
    def provide_sqlite_connection(
            self, configuration: Configuration) -> sqlite3.Connection:
        conn = sqlite3.connect(configuration['db_connection_string'])
        cursor = conn.cursor()
        cursor.execute(
            'CREATE TABLE IF NOT EXISTS data (key PRIMARY KEY, value)')
        cursor.execute('INSERT OR REPLACE INTO data VALUES ("hello", "world")')
        return conn


if __name__ == "__main__":
    injector = Injector([configure_for_testing, DatabaseModule()])
    handler = injector.get(RequestHandler)
    print(tuple(map(str, handler.get()[0])))
    def __init__(
        self,
        app: flask.Flask,
        modules: Iterable[_ModuleT] = [],
        injector: Injector = None,
        request_scope_class: type = RequestScope,
    ) -> None:
        """Initializes Injector for the application.

        .. note::

            Needs to be called *after* all views, signal handlers, template globals
            and context processors are registered.

        :param app: Application to configure
        :param modules: Configuration for newly created :class:`injector.Injector`
        :param injector: Injector to initialize app with, if not provided
            a new instance will be created.
        :type app: :class:`flask.Flask`
        :type modules: Iterable of configuration modules
        :rtype: :class:`injector.Injector`
        """
        if not injector:
            injector = Injector()

        modules = list(modules)
        modules.insert(0, FlaskModule(app=app, request_scope_class=request_scope_class))
        for module in modules:
            injector.binder.install(module)

        for container in (
                app.view_functions,
                app.before_request_funcs,
                app.after_request_funcs,
                app.teardown_request_funcs,
                app.template_context_processors,
                app.jinja_env.globals,
                app.error_handler_spec,
        ):
            process_dict(container, injector)

        process_list(app.before_first_request_funcs, injector)

        # This is to make sure that mypy sees a non-nullable variable
        # in the closures below, otherwise it'd complain that injector
        # union may not have get attribute
        injector_not_null = injector

        def reset_request_scope_before(*args: Any, **kwargs: Any) -> None:
            injector_not_null.get(request_scope_class).prepare()

        def reset_request_scope_after(*args: Any, **kwargs: Any) -> None:
            injector_not_null.get(request_scope_class).cleanup()

        app.before_request_funcs.setdefault(
            None, []).insert(0, reset_request_scope_before)
        app.teardown_request(reset_request_scope_after)

        self.injector = injector_not_null
        self.app = app

        # Store the FlaskInjector on the application so it can be fetched
        # via flask.current_app for use with @flask_inject.
        self.app.extensions['flask_injector'] = self
Example #58
0
    @inject
    def __init__(self, greet: Greet, map: Map):
        self.greet = greet
        self.map = map


def first(binder: Binder):
    binder.bind(Greet, 'hello')
    binder.bind(Map, {'a': "hi"})


def second(binder: Binder):
    binder.bind(Greet, 'world')
    binder.bind(Map, {'a': "bye", 'b': 'extra'})


def third(binder: Binder):
    binder.bind(Greet, 'Morning')
    binder.bind(Map, {'c': 'third'})


context = Injector([first, second, third])
a = context.get(Foo)

assert a.greet == "Morning"
assert a.map['c'] == 'third'
assert a.map['b'] == 'extra'
assert a.map['a'] == 'bye'

print(a.map)
Example #59
0
from flask.cli import FlaskGroup
from flask_debugtoolbar import DebugToolbarExtension
from flask_injector import FlaskInjector
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from injector import Injector, Module, provider, singleton
from raven.contrib.celery import register_logger_signal, register_signal
from raven.contrib.flask import Sentry

from .commands import setup_cli
from .filters import register as register_filters
from .scheme import metadata

db = SQLAlchemy(metadata=metadata)

injector = Injector()


class SQLAlchemyModule(Module):
    @provider
    @singleton
    def provide_db(self, app: Flask) -> SQLAlchemy:
        return db


class CeleryModule(Module):
    @provider
    @singleton
    def provide_celery(self, app: Flask) -> Celery:
        celery = Celery(
            app.import_name,
Example #60
0
from injector import Injector

from rpg_music.users.repositories.user.redis import RedisUserRepository
from rpg_music.users.repositories.user_auth.redis import RedisUserAuthRepository

injector = Injector([RedisUserRepository(), RedisUserAuthRepository()])