diff --git a/src/blueapi/client/client.py b/src/blueapi/client/client.py index 486f3b86d..2e805ea74 100644 --- a/src/blueapi/client/client.py +++ b/src/blueapi/client/client.py @@ -47,14 +47,14 @@ def __init__( def from_config(cls, config: ApplicationConfig) -> "BlueapiClient": rest = BlueapiRestClient(config.api) if config.stomp is not None: - template = StompClient.for_broker( + stomp_client = StompClient.for_broker( broker=Broker( host=config.stomp.host, port=config.stomp.port, auth=config.stomp.auth, ) ) - events = EventBusClient(template) + events = EventBusClient(stomp_client) else: events = None return cls(rest, events) diff --git a/src/blueapi/core/context.py b/src/blueapi/core/context.py index 429ef4d77..c92c38113 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/core/context.py @@ -107,7 +107,7 @@ def plan_2(...) -> MsgGenerator: for obj in load_module_all(module): if is_bluesky_plan_generator(obj): - self.plan(obj) + self.register_plan(obj) def with_device_module(self, module: ModuleType) -> None: self.with_dodal_module(module) @@ -116,7 +116,7 @@ def with_dodal_module(self, module: ModuleType, **kwargs) -> None: devices, exceptions = make_all_devices(module, **kwargs) for device in devices.values(): - self.device(device) + self.register_device(device) # If exceptions have occurred, we log them but we do not make blueapi # fall over @@ -126,7 +126,7 @@ def with_dodal_module(self, module: ModuleType, **kwargs) -> None: ) LOGGER.exception(NotConnected(exceptions)) - def plan(self, plan: PlanGenerator) -> PlanGenerator: + def register_plan(self, plan: PlanGenerator) -> PlanGenerator: """ Register the argument as a plan in the context. Can be used as a decorator e.g. @ctx.plan @@ -154,7 +154,7 @@ def my_plan(a: int, b: str): self.plan_functions[plan.__name__] = plan return plan - def device(self, device: Device, name: str | None = None) -> None: + def register_device(self, device: Device, name: str | None = None) -> None: """ Register an device in the context. The device needs to be registered with a name. If the device is Readable, Movable or Flyable it has a `name` diff --git a/src/blueapi/service/interface.py b/src/blueapi/service/interface.py index 2fe820abb..ceb8eb980 100644 --- a/src/blueapi/service/interface.py +++ b/src/blueapi/service/interface.py @@ -52,7 +52,7 @@ def worker() -> TaskWorker: def stomp_client() -> StompClient | None: stomp_config = config().stomp if stomp_config is not None: - template = StompClient.for_broker( + stomp_client = StompClient.for_broker( broker=Broker( host=stomp_config.host, port=stomp_config.port, auth=stomp_config.auth ) @@ -68,8 +68,8 @@ def stomp_client() -> StompClient | None: task_worker.data_events: event_topic, } ) - template.connect() - return template + stomp_client.connect() + return stomp_client else: return None @@ -88,8 +88,8 @@ def setup(config: ApplicationConfig) -> None: def teardown() -> None: worker().stop() - if (template := stomp_client()) is not None: - template.disconnect() + if (stomp_client_ref := stomp_client()) is not None: + stomp_client_ref.disconnect() context.cache_clear() worker.cache_clear() stomp_client.cache_clear() @@ -104,8 +104,10 @@ def _publish_event_streams( def _publish_event_stream(stream: EventStream, destination: DestinationBase) -> None: def forward_message(event: Any, correlation_id: str | None) -> None: - if (template := stomp_client()) is not None: - template.send(destination, event, None, correlation_id=correlation_id) + if (stomp_client_ref := stomp_client()) is not None: + stomp_client_ref.send( + destination, event, None, correlation_id=correlation_id + ) stream.subscribe(forward_message) diff --git a/src/blueapi/service/main.py b/src/blueapi/service/main.py index 05c529d7d..11ad7271f 100644 --- a/src/blueapi/service/main.py +++ b/src/blueapi/service/main.py @@ -133,7 +133,8 @@ async def delete_environment( @start_as_current_span(TRACER) def get_plans(runner: WorkerDispatcher = Depends(_runner)): """Retrieve information about all available plans.""" - return PlanResponse(plans=runner.run(interface.get_plans)) + plans = runner.run(interface.get_plans) + return PlanResponse(plans=plans) @router.get( @@ -150,7 +151,8 @@ def get_plan_by_name(name: str, runner: WorkerDispatcher = Depends(_runner)): @start_as_current_span(TRACER) def get_devices(runner: WorkerDispatcher = Depends(_runner)): """Retrieve information about all available devices.""" - return DeviceResponse(devices=runner.run(interface.get_devices)) + devices = runner.run(interface.get_devices) + return DeviceResponse(devices=devices) @router.get( @@ -285,10 +287,8 @@ def get_task( @start_as_current_span(TRACER) def get_active_task(runner: WorkerDispatcher = Depends(_runner)) -> WorkerTask: active = runner.run(interface.get_active_task) - if active is not None: - return WorkerTask(task_id=active.task_id) - else: - return WorkerTask(task_id=None) + task_id = active.task_id if active is not None else None + return WorkerTask(task_id=task_id) @router.get("/worker/state") diff --git a/tests/unit_tests/client/test_event_bus.py b/tests/unit_tests/client/test_event_bus.py index 34ac41a63..89f5b5ef2 100644 --- a/tests/unit_tests/client/test_event_bus.py +++ b/tests/unit_tests/client/test_event_bus.py @@ -7,44 +7,44 @@ @pytest.fixture -def mock_template() -> StompClient: +def mock_stomp_client() -> StompClient: return Mock(spec=StompClient) @pytest.fixture -def events(mock_template: StompClient) -> EventBusClient: - return EventBusClient(app=mock_template) +def events(mock_stomp_client: StompClient) -> EventBusClient: + return EventBusClient(app=mock_stomp_client) def test_context_manager_connects_and_disconnects( events: EventBusClient, - mock_template: Mock, + mock_stomp_client: Mock, ): - mock_template.connect.assert_not_called() - mock_template.disconnect.assert_not_called() + mock_stomp_client.connect.assert_not_called() + mock_stomp_client.disconnect.assert_not_called() with events: - mock_template.connect.assert_called_once() - mock_template.disconnect.assert_not_called() + mock_stomp_client.connect.assert_called_once() + mock_stomp_client.disconnect.assert_not_called() - mock_template.disconnect.assert_called_once() + mock_stomp_client.disconnect.assert_called_once() def test_client_subscribes_to_all_events( events: EventBusClient, - mock_template: Mock, + mock_stomp_client: Mock, ): on_event = Mock with events: events.subscribe_to_all_events(on_event=on_event) # type: ignore - mock_template.subscribe.assert_called_once_with(ANY, on_event) + mock_stomp_client.subscribe.assert_called_once_with(ANY, on_event) def test_client_raises_streaming_error_on_subscribe_failure( events: EventBusClient, - mock_template: Mock, + mock_stomp_client: Mock, ): - mock_template.subscribe.side_effect = RuntimeError("Foo") + mock_stomp_client.subscribe.side_effect = RuntimeError("Foo") on_event = Mock with events: with pytest.raises( diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index c7b1ad8ef..0540401f2 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -96,8 +96,8 @@ def empty_context() -> BlueskyContext: @pytest.fixture def devicey_context(sim_motor: SynAxis, sim_detector: SynGauss) -> BlueskyContext: ctx = BlueskyContext() - ctx.device(sim_motor) - ctx.device(sim_detector) + ctx.register_device(sim_motor) + ctx.register_device(sim_detector) return ctx @@ -117,7 +117,7 @@ def some_configurable() -> SomeConfigurable: @pytest.mark.parametrize("plan", [has_no_params, has_one_param, has_some_params]) def test_add_plan(empty_context: BlueskyContext, plan: PlanGenerator) -> None: - empty_context.plan(plan) + empty_context.register_plan(plan) assert plan.__name__ in empty_context.plans @@ -127,7 +127,7 @@ def test_generated_schema( def demo_plan(foo: int, mov: Movable) -> MsgGenerator: # type: ignore ... - empty_context.plan(demo_plan) + empty_context.register_plan(demo_plan) schema = empty_context.plans["demo_plan"].model.schema() assert schema["properties"] == { "foo": {"title": "Foo", "type": "integer"}, @@ -140,7 +140,7 @@ def demo_plan(foo: int, mov: Movable) -> MsgGenerator: # type: ignore ) def test_add_invalid_plan(empty_context: BlueskyContext, plan: PlanGenerator) -> None: with pytest.raises(ValueError): - empty_context.plan(plan) + empty_context.register_plan(plan) def test_add_plan_from_module(empty_context: BlueskyContext) -> None: @@ -151,14 +151,14 @@ def test_add_plan_from_module(empty_context: BlueskyContext) -> None: def test_add_named_device(empty_context: BlueskyContext, sim_motor: SynAxis) -> None: - empty_context.device(sim_motor) + empty_context.register_device(sim_motor) assert empty_context.devices[SIM_MOTOR_NAME] is sim_motor def test_add_nameless_device( empty_context: BlueskyContext, some_configurable: SomeConfigurable ) -> None: - empty_context.device(some_configurable, "conf") + empty_context.register_device(some_configurable, "conf") assert empty_context.devices["conf"] is some_configurable @@ -167,13 +167,13 @@ def test_add_nameless_device_without_override( some_configurable: SomeConfigurable, ) -> None: with pytest.raises(KeyError): - empty_context.device(some_configurable) + empty_context.register_device(some_configurable) def test_override_device_name( empty_context: BlueskyContext, sim_motor: SynAxis ) -> None: - empty_context.device(sim_motor, "foo") + empty_context.register_device(sim_motor, "foo") assert empty_context.devices["foo"] is sim_motor @@ -246,12 +246,12 @@ def test_lookup_non_device(devicey_context: BlueskyContext) -> None: def test_add_non_plan(empty_context: BlueskyContext) -> None: with pytest.raises(TypeError): - empty_context.plan("not a plan") # type: ignore + empty_context.register_plan("not a plan") # type: ignore def test_add_non_device(empty_context: BlueskyContext) -> None: with pytest.raises(TypeError): - empty_context.device("not a device") # type: ignore + empty_context.register_device("not a device") # type: ignore def test_add_devices_and_plans_from_modules_with_config( @@ -362,8 +362,8 @@ def test_str_default( empty_context: BlueskyContext, sim_motor: SynAxis, alt_motor: SynAxis ): movable_ref = empty_context._reference(Movable) - empty_context.device(sim_motor) - empty_context.plan(has_default_reference) + empty_context.register_device(sim_motor) + empty_context.register_plan(has_default_reference) spec = empty_context._type_spec_for_function(has_default_reference) assert spec["m"][0] is movable_ref @@ -373,7 +373,7 @@ def test_str_default( model = empty_context.plans[has_default_reference.__name__].model adapter = TypeAdapter(model) assert adapter.validate_python({}).m is sim_motor # type: ignore - empty_context.device(alt_motor) + empty_context.register_device(alt_motor) assert adapter.validate_python({"m": ALT_MOTOR_NAME}).m is alt_motor # type: ignore @@ -381,8 +381,8 @@ def test_nested_str_default( empty_context: BlueskyContext, sim_motor: SynAxis, alt_motor: SynAxis ): movable_ref = empty_context._reference(Movable) - empty_context.device(sim_motor) - empty_context.plan(has_default_nested_reference) + empty_context.register_device(sim_motor) + empty_context.register_plan(has_default_nested_reference) spec = empty_context._type_spec_for_function(has_default_nested_reference) assert spec["m"][0] == list[movable_ref] # type: ignore @@ -393,7 +393,7 @@ def test_nested_str_default( adapter = TypeAdapter(model) assert adapter.validate_python({}).m == [sim_motor] # type: ignore - empty_context.device(alt_motor) + empty_context.register_device(alt_motor) assert adapter.validate_python({"m": [ALT_MOTOR_NAME]}).m == [alt_motor] # type: ignore @@ -402,6 +402,6 @@ def a_plan(foo_bar: int, baz: str) -> MsgGenerator: if False: yield - empty_context.plan(a_plan) + empty_context.register_plan(a_plan) with pytest.raises(ValidationError): empty_context.plans[a_plan.__name__].model(fooBar=1, baz="test") diff --git a/tests/unit_tests/service/test_interface.py b/tests/unit_tests/service/test_interface.py index 654881916..8faf91332 100644 --- a/tests/unit_tests/service/test_interface.py +++ b/tests/unit_tests/service/test_interface.py @@ -23,10 +23,10 @@ def mock_connection() -> Mock: @pytest.fixture -def template(mock_connection: Mock) -> StompClient: - template = StompClient(conn=mock_connection) - template.disconnect = MagicMock() - return template +def mock_stomp_client(mock_connection: Mock) -> StompClient: + stomp_client = StompClient(conn=mock_connection) + stomp_client.disconnect = MagicMock() + return stomp_client @pytest.fixture(autouse=True) @@ -52,8 +52,8 @@ def my_second_plan(repeats: int) -> MsgGenerator: @patch("blueapi.service.interface.context") def test_get_plans(context_mock: MagicMock): context = BlueskyContext() - context.plan(my_plan) - context.plan(my_second_plan) + context.register_plan(my_plan) + context.register_plan(my_second_plan) context_mock.return_value = context assert interface.get_plans() == [ @@ -84,8 +84,8 @@ def test_get_plans(context_mock: MagicMock): @patch("blueapi.service.interface.context") def test_get_plan(context_mock: MagicMock): context = BlueskyContext() - context.plan(my_plan) - context.plan(my_second_plan) + context.register_plan(my_plan) + context.register_plan(my_second_plan) context_mock.return_value = context assert interface.get_plan("my_plan") == PlanModel( @@ -111,8 +111,8 @@ class MyDevice: @patch("blueapi.service.interface.context") def test_get_devices(context_mock: MagicMock): context = BlueskyContext() - context.device(MyDevice(name="my_device")) - context.device(SynAxis(name="my_axis")) + context.register_device(MyDevice(name="my_device")) + context.register_device(SynAxis(name="my_axis")) context_mock.return_value = context assert interface.get_devices() == [ @@ -140,7 +140,7 @@ def test_get_devices(context_mock: MagicMock): @patch("blueapi.service.interface.context") def test_get_device(context_mock: MagicMock): context = BlueskyContext() - context.device(MyDevice(name="my_device")) + context.register_device(MyDevice(name="my_device")) context_mock.return_value = context assert interface.get_device("my_device") == DeviceModel( @@ -154,7 +154,7 @@ def test_get_device(context_mock: MagicMock): @patch("blueapi.service.interface.context") def test_submit_task(context_mock: MagicMock): context = BlueskyContext() - context.plan(my_plan) + context.register_plan(my_plan) task = Task(name="my_plan") context_mock.return_value = context mock_uuid_value = "8dfbb9c2-7a15-47b6-bea8-b6b77c31d3d9" @@ -167,7 +167,7 @@ def test_submit_task(context_mock: MagicMock): @patch("blueapi.service.interface.context") def test_clear_task(context_mock: MagicMock): context = BlueskyContext() - context.plan(my_plan) + context.register_plan(my_plan) task = Task(name="my_plan") context_mock.return_value = context mock_uuid_value = "3d858a62-b40a-400f-82af-8d2603a4e59a" @@ -269,7 +269,7 @@ def test_get_tasks(get_tasks_mock: MagicMock): @patch("blueapi.service.interface.context") def test_get_task_by_id(context_mock: MagicMock): context = BlueskyContext() - context.plan(my_plan) + context.register_plan(my_plan) context_mock.return_value = context task_id = interface.submit_task(Task(name="my_plan")) @@ -284,9 +284,10 @@ def test_get_task_by_id(context_mock: MagicMock): ) -def test_stomp_config(template: StompClient): +def test_stomp_config(mock_stomp_client: StompClient): with patch( - "blueapi.service.interface.StompClient.for_broker", return_value=template + "blueapi.service.interface.StompClient.for_broker", + return_value=mock_stomp_client, ): interface.set_config(ApplicationConfig(stomp=StompConfig())) assert interface.stomp_client() is not None diff --git a/tests/unit_tests/test_cli.py b/tests/unit_tests/test_cli.py index 370a90e85..b6c75eea9 100644 --- a/tests/unit_tests/test_cli.py +++ b/tests/unit_tests/test_cli.py @@ -38,7 +38,7 @@ def mock_connection() -> Mock: @pytest.fixture -def template(mock_connection: Mock) -> StompClient: +def mock_stomp_client(mock_connection: Mock) -> StompClient: return StompClient(conn=mock_connection) @@ -152,7 +152,7 @@ def test_cannot_run_plans_without_stomp_config(runner: CliRunner): @patch("blueapi.cli.cli.StompClient") def test_valid_stomp_config_for_listener( - template: StompClient, + mock_stomp_client: StompClient, runner: CliRunner, mock_connection: Mock, ): diff --git a/tests/unit_tests/worker/test_task_worker.py b/tests/unit_tests/worker/test_task_worker.py index 9d9028a18..1a6f56d7b 100644 --- a/tests/unit_tests/worker/test_task_worker.py +++ b/tests/unit_tests/worker/test_task_worker.py @@ -68,8 +68,8 @@ def context(fake_device: FakeDevice) -> BlueskyContext: ctx_config.sources.append( Source(kind=SourceKind.DEVICE_FUNCTIONS, module="devices") ) - ctx.plan(failing_plan) - ctx.device(fake_device) + ctx.register_plan(failing_plan) + ctx.register_device(fake_device) ctx.with_config(ctx_config) return ctx