async def inner(): transport = TransactionalEventTransport( child_transport=lightbus.RedisEventTransport( redis_pool=pool, consumer_group_prefix="test_cg", consumer_name="test_consumer", stream_use=StreamUse.PER_EVENT, ) ) config = dummy_bus.client.config transport_registry = TransportRegistry().load_config(config) transport_registry.set_event_transport("default", transport) client = lightbus.BusClient(config=config, transport_registry=transport_registry) bus = lightbus.path.BusPath(name="", parent=None, client=client) return bus
def __init_worker___(self): self.transport_registry = self.transport_registry or TransportRegistry().load_config( self.config ) schema = Schema( schema_transport=self.transport_registry.get_schema_transport(), max_age_seconds=self.config.bus().schema.ttl, human_readable=self.config.bus().schema.human_readable, ) self.schema = WorkerProxy(proxied=schema, worker=self.worker)
def test_setup_transports_opened(mocker): rpc_transport = lightbus.DebugRpcTransport() # TODO: There has to be a cleaner way of patching a coroutine. # Do a global search for 'dummy_coroutine' if you find it async def dummy_coroutine(*args, **kwargs): pass m = mocker.patch.object(rpc_transport, "open", autospec=True, return_value=dummy_coroutine()) transport_registry = TransportRegistry().load_config(Config.load_dict({})) transport_registry.set_rpc_transport("default", rpc_transport) bus = lightbus.creation.create(transport_registry=transport_registry, plugins=[]) try: assert m.call_count == 0 bus.client.lazy_load_now() assert m.call_count == 1 finally: bus.client.close()
def test_transport_registry_get_specific_api(redis_other_config): registry = TransportRegistry().load_config(redis_other_config) assert registry.get_rpc_transport("other").__class__ == RedisRpcTransport assert registry.get_result_transport( "other").__class__ == RedisResultTransport assert registry.get_event_transport( "other").__class__ == RedisEventTransport assert registry.get_schema_transport( "other").__class__ == RedisSchemaTransport
def test_transport_registry_load_config(redis_default_config): registry = TransportRegistry().load_config(redis_default_config) assert registry.get_rpc_transport("default").__class__ == RedisRpcTransport assert registry.get_result_transport( "default").__class__ == RedisResultTransport assert registry.get_event_transport( "default").__class__ == RedisEventTransport assert registry.get_schema_transport( "default").__class__ == RedisSchemaTransport
def test_transport_registry_get_does_not_exist_default(): registry = TransportRegistry() with pytest.raises(TransportNotFound): assert not registry.get_rpc_transport("default") with pytest.raises(TransportNotFound): assert not registry.get_result_transport("default") with pytest.raises(TransportNotFound): assert not registry.get_event_transport("default") with pytest.raises(TransportNotFound): assert not registry.get_schema_transport()
def __init__(self, config: "Config", transport_registry: TransportRegistry = None): self.config = config self.transport_registry = transport_registry or TransportRegistry( ).load_config(config) self.schema = Schema( schema_transport=self.transport_registry.get_schema_transport( "default"), max_age_seconds=self.config.bus().schema.ttl, human_readable=self.config.bus().schema.human_readable, ) self._listeners = {} self._hook_callbacks = defaultdict(list) self._exit_code = 0
def test_transport_registry_get_rpc_transports(redis_default_config): registry = TransportRegistry().load_config(redis_default_config) debug_transport = DebugRpcTransport() redis_transport = RedisRpcTransport() registry.set_rpc_transport("redis1", redis_transport) registry.set_rpc_transport("redis2", redis_transport) registry.set_rpc_transport("debug1", debug_transport) registry.set_rpc_transport("debug2", debug_transport) transports = registry.get_rpc_transports( ["default", "foo", "bar", "redis1", "redis2", "debug1", "debug2"]) default_redis_transport = registry.get_rpc_transport("default") transports = dict(transports) assert set( transports[default_redis_transport]) == {"default", "foo", "bar"} assert set(transports[debug_transport]) == {"debug1", "debug2"} assert set(transports[redis_transport]) == {"redis1", "redis2"}
def test_transport_registry_get_event_transports(redis_default_config): registry = TransportRegistry().load_config(redis_default_config) debug_transport = DebugEventTransport() redis_transport = RedisEventTransport(service_name="foo", consumer_name="bar") registry.set_event_transport("redis1", redis_transport) registry.set_event_transport("redis2", redis_transport) registry.set_event_transport("debug1", debug_transport) registry.set_event_transport("debug2", debug_transport) transports = registry.get_event_transports( ["default", "foo", "bar", "redis1", "redis2", "debug1", "debug2"] ) default_redis_transport = registry.get_event_transport("default") transports = dict(transports) assert set(transports[default_redis_transport]) == {"default", "foo", "bar"} assert set(transports[debug_transport]) == {"debug1", "debug2"} assert set(transports[redis_transport]) == {"redis1", "redis2"}
def __enter__(self): rpc = TestRpcTransport() result = TestResultTransport() event = TestEventTransport() schema = TestSchemaTransport() new_registry = TransportRegistry() new_registry.set_schema_transport(schema) self.old_transport_registry = self.bus.client.transport_registry for api_name, entry in self.old_transport_registry._registry.items(): new_registry.set_rpc_transport(api_name, rpc) new_registry.set_result_transport(api_name, result) if hasattr(entry.event, "child_transport"): parent_transport = copy(entry.event) parent_transport.child_transport = event new_registry.set_event_transport(api_name, parent_transport) else: new_registry.set_event_transport(api_name, event) self.bus.client.transport_registry = new_registry return MockResult(rpc, result, event, schema)
def test_has_schema_transport(redis_no_default_config): registry = TransportRegistry().load_config(redis_no_default_config) assert registry.has_schema_transport() registry.schema_transport = None assert not registry.has_schema_transport()
def test_has_event_transport(redis_no_default_config): registry = TransportRegistry().load_config(redis_no_default_config) assert registry.has_event_transport("other") assert not registry.has_event_transport("foo")
def test_get_all_transports(redis_default_config): registry = TransportRegistry().load_config(redis_default_config) registry.set_event_transport("another", registry.get_event_transport("default")) registry.set_event_transport("foo", DebugEventTransport()) assert len(registry.get_all_transports()) == 4
async def create_async( config: Union[dict, Config] = None, *, config_file: str = None, service_name: str = None, process_name: str = None, rpc_transport: Optional["RpcTransport"] = None, result_transport: Optional["ResultTransport"] = None, event_transport: Optional["EventTransport"] = None, schema_transport: Optional["SchemaTransport"] = None, client_class=BusClient, node_class=BusPath, plugins=None, flask: bool = False, **kwargs, ) -> BusPath: """ Create a new bus instance which can be used to access the bus. Typically this will be used as follows: import lightbus bus = await lightbus.create_async() This will be a `BusPath` instance. If you wish to access the lower level `BusClient` you can do so via `bus.client`. See Also: `create()` - The synchronous wrapper for this function Args: config (dict, Config): The config object or dictionary to load config_file (str): The path to a config file to load (should end in .json or .yaml) service_name (str): The name of this service - will be used when creating event consumer groups process_name (str): The unique name of this process - used when retrieving unprocessed events following a crash rpc_transport (RpcTransport): The RPC transport instance to use, defaults to Redis result_transport (ResultTransport): The result transport instance to use, defaults to Redis event_transport (EventTransport): The event transport instance to use, defaults to Redis schema_transport (SchemaTransport): The schema transport instance to use, defaults to Redis client_class (BusClient): The class from which the bus client will be instantiated node_class (BusPath): The class from which the bus path will be instantiated plugins (dict): A dictionary of plugins to load, where keys are the plugin name defined in the plugin's entrypoint flask (bool): Are we using flask? If so we will make sure we don't start lightbus in the reloader process **kwargs (): Any additional instantiation arguments to be passed to `client_class`. Returns: """ if flask: in_flask_server = sys.argv[0].endswith("flask") and "run" in sys.argv if in_flask_server and os.environ.get("WERKZEUG_RUN_MAIN", "").lower() != "true": # Flask has a reloader process that shouldn't start a lightbus client return from lightbus.config import Config # If were are running via the Lightbus CLI then we may have # some command line arguments we need to apply. from lightbus.commands import COMMAND_PARSED_ARGS config_file = COMMAND_PARSED_ARGS.get("config_file", None) or config_file service_name = COMMAND_PARSED_ARGS.get("service_name", None) or service_name process_name = COMMAND_PARSED_ARGS.get("process_name", None) or process_name if config is None: config = load_config(from_file=config_file, service_name=service_name, process_name=process_name) if isinstance(config, Mapping): config = Config.load_dict(config or {}) transport_registry = TransportRegistry().load_config(config) # Set transports if specified if rpc_transport: transport_registry.set_rpc_transport("default", rpc_transport) if result_transport: transport_registry.set_result_transport("default", result_transport) if event_transport: transport_registry.set_event_transport("default", event_transport) if schema_transport: transport_registry.set_schema_transport(schema_transport) client = client_class(transport_registry=transport_registry, config=config, **kwargs) await client.setup_async(plugins=plugins) return node_class(name="", parent=None, client=client)
def test_transport_registry_get_does_not_exist_default_default_value(): registry = TransportRegistry() assert registry.get_rpc_transport("default", default=None) is None assert registry.get_result_transport("default", default=None) is None assert registry.get_event_transport("default", default=None) is None assert registry.get_schema_transport(default=None) is None
def create( config: Union[dict, RootConfig] = None, *, config_file: str = None, service_name: str = None, process_name: str = None, features: List[Union[Feature, str]] = ALL_FEATURES, client_class: Type[BusClient] = BusClient, node_class: Type[BusPath] = BusPath, plugins=None, flask: bool = False, **kwargs, ) -> BusPath: """ Create a new bus instance which can be used to access the bus. Typically this will be used as follows: import lightbus bus = lightbus.create() This will be a `BusPath` instance. If you wish to access the lower level `BusClient` you can do so via `bus.client`. Args: config (dict, Config): The config object or dictionary to load config_file (str): The path to a config file to load (should end in .json or .yaml) service_name (str): The name of this service - will be used when creating event consumer groups process_name (str): The unique name of this process - used when retrieving unprocessed events following a crash client_class (Type[BusClient]): The class from which the bus client will be instantiated node_class (BusPath): The class from which the bus path will be instantiated plugins (list): A list of plugin instances to load flask (bool): Are we using flask? If so we will make sure we don't start lightbus in the reloader process **kwargs (): Any additional instantiation arguments to be passed to `client_class`. Returns: BusPath """ if flask: in_flask_server = sys.argv[0].endswith("flask") and "run" in sys.argv if in_flask_server and os.environ.get("WERKZEUG_RUN_MAIN", "").lower() != "true": # Flask has a reloader process that shouldn't start a lightbus client return # If were are running via the Lightbus CLI then we may have # some command line arguments we need to apply. # pylint: disable=cyclic-import,import-outside-toplevel from lightbus.commands import COMMAND_PARSED_ARGS config_file = COMMAND_PARSED_ARGS.get("config_file", None) or config_file service_name = COMMAND_PARSED_ARGS.get("service_name", None) or service_name process_name = COMMAND_PARSED_ARGS.get("process_name", None) or process_name if config is None: config = load_config( from_file=config_file, service_name=service_name, process_name=process_name ) if isinstance(config, Mapping): config = Config.load_dict(config or {}) elif isinstance(config, RootConfig): config = Config(config) transport_registry = kwargs.pop("transport_registry", None) or TransportRegistry().load_config( config ) client = client_class( transport_registry=transport_registry, config=config, features=features, plugins=plugins, **kwargs, ) return node_class(name="", parent=None, client=client)
def __enter__(self): """Start of a context where all the bus' transports have been replaced with mocks""" rpc = TestRpcTransport() result = TestResultTransport(require_mocking=self.require_mocking) event = TestEventTransport(require_mocking=self.require_mocking) schema = TestSchemaTransport() new_registry = TransportRegistry() new_registry.set_schema_transport(schema) self.old_transport_registry = self.bus.client.transport_registry for api_name, entry in self.old_transport_registry._registry.items(): new_registry.set_rpc_transport(api_name, rpc) new_registry.set_result_transport(api_name, result) if hasattr(entry.event, "child_transport"): parent_transport = copy(entry.event) parent_transport.child_transport = event new_registry.set_event_transport(api_name, parent_transport) else: new_registry.set_event_transport(api_name, event) self.bus.client.transport_registry = new_registry return MockResult(rpc, result, event, schema)