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'
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"))
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))
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 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)
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)
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()
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]
def prepare_nested_injectors(): def configure(binder): binder.bind(str, to='asd') parent = Injector(configure) child = parent.create_child_injector() return parent, child
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)
def test_auto_bind(): class A(object): pass injector = Injector() assert (isinstance(injector.get(A), A))
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()})
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
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
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)
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)
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"
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'
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)
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)
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')
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)
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))
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)
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))
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))
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)
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
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))
@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()
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)
def inject_packet_logger(pid: int): injector = Injector() injector.load_from_pid(pid) injector.inject_dll(get_packet_logger_path(pid))
def test_auto_bind(): class A: pass injector = Injector() assert isinstance(injector.get(A), A)
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
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
def _get_storage() -> Storage: injector = Injector(modules=[ApplicationModule]) storage = injector.get(Storage) click.echo(storage.config) return storage
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")
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()
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()])
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
def register_extensions(app): db.init_app(app) Migrate(app, db) injector = Injector([PaymentManagerModule(app)]) FlaskInjector(app=app, injector=injector)
def get(self, injector: Injector) -> List[T]: return [injector.create_object(self._cls)]
def get_injector() -> Injector: global _injector if _injector is None: _injector = Injector([InjectorConfiguration]) return _injector
from injector import Injector from .db import PersistenceModule from .subscription.plan import SubscriptionPlanModule register: Injector = Injector([PersistenceModule, SubscriptionPlanModule]) __all__ = ['register']
def setUp(self): injector = Injector([ProcessorsModule()]) self.img_to_text_service = injector.get(ImageToTextService)
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)
def setUp(self): configure_logging(logging.INFO) injector = Injector([DefaultModule]) self.asset_service = injector.get(AssetService) self.service = injector.get(FactorService)
def test_optionals_are_ignored_for_now(): @inject def fun(s: str = None): return s assert Injector().call_with_injection(fun) == ''
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)
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
@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)
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,
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()])