From e38353b8604cc6a91cb4bd92febc55b55e6dc707 Mon Sep 17 00:00:00 2001 From: Oli Wenman Date: Wed, 22 Apr 2026 15:54:02 +0000 Subject: [PATCH 1/8] Add a generic blueapi client --- pyproject.toml | 2 +- src/sm_bluesky/clients/__init__.py | 0 src/sm_bluesky/clients/blueapi_client.py | 60 ++++++++++++++++++++++++ uv.lock | 4 +- 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/sm_bluesky/clients/__init__.py create mode 100644 src/sm_bluesky/clients/blueapi_client.py diff --git a/pyproject.toml b/pyproject.toml index 9906c851..bcf70651 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ dependencies = [ "dls-dodal>=2.2.0", "ophyd-async[sim]", "scanspec", + "blueapi", ] dynamic = ["version"] license.file = "LICENSE" @@ -52,7 +53,6 @@ dev = [ "matplotlib", "numpy", "pyepics", - "blueapi", ] [project.scripts] diff --git a/src/sm_bluesky/clients/__init__.py b/src/sm_bluesky/clients/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sm_bluesky/clients/blueapi_client.py b/src/sm_bluesky/clients/blueapi_client.py new file mode 100644 index 00000000..d7997cf9 --- /dev/null +++ b/src/sm_bluesky/clients/blueapi_client.py @@ -0,0 +1,60 @@ +""" +Start this script by running: +$ python -i src/sm_bluesky/clients/i09/blueapi_client.py +""" + +from os import environ + +from blueapi.client import BlueapiClient +from blueapi.config import ApplicationConfig, HttpUrl, RestConfig, StompConfig, TcpUrl +from blueapi.core.bluesky_types import DataEvent + +BEAMLINE = environ.get("BEAMLINE") +if BEAMLINE is None: + raise RuntimeError("BEAMLINE environment variable not set.") + + +print(f"Starting BlueAPI client for {BEAMLINE}.") +bc = BlueapiClient.from_config( + ApplicationConfig( + api=RestConfig(url=HttpUrl(f"https://{BEAMLINE}-blueapi.diamond.ac.uk")), + stomp=StompConfig( + enabled=True, + url=TcpUrl(f"tcp://{BEAMLINE}-rabbitmq-daq.diamond.ac.uk:61613"), + ), + ) +) +print("Logging in...") +bc.login() + + +def _feedback(evt): + match evt: + case DataEvent(name="start"): + print("Run started") + case DataEvent(name="stop", doc={"exit_status": status}): + print("Run complete: ", status) + case DataEvent(name="event", doc={"seq_num": point, "data": data}): + print(f" Point {point}: {data}") + + +feedback_id = bc.add_callback(_feedback) +print("Installed feedback.") + +print("\nGetting devices and plans...") +devs = bc.devices +plans = bc.plans +print(devs) +print(plans) + +print("Please remember to configure the correct instrument session for bc.") + + +def show_devices(bc: BlueapiClient = bc): + for device in bc.devices: + print(device) + + +def show_plans(bc: BlueapiClient = bc): + for plan in bc.plans: + print(plan) diff --git a/uv.lock b/uv.lock index e7cbf2d4..05c70987 100644 --- a/uv.lock +++ b/uv.lock @@ -5470,6 +5470,7 @@ wheels = [ name = "sm-bluesky" source = { editable = "." } dependencies = [ + { name = "blueapi" }, { name = "bluesky" }, { name = "dls-dodal" }, { name = "ophyd-async", extra = ["sim"] }, @@ -5478,7 +5479,6 @@ dependencies = [ [package.dev-dependencies] dev = [ - { name = "blueapi" }, { name = "chardet" }, { name = "copier" }, { name = "ipython", version = "9.10.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, @@ -5504,6 +5504,7 @@ dev = [ [package.metadata] requires-dist = [ + { name = "blueapi" }, { name = "bluesky" }, { name = "dls-dodal", specifier = ">=2.2.0" }, { name = "ophyd-async", extras = ["sim"] }, @@ -5512,7 +5513,6 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ - { name = "blueapi" }, { name = "chardet", specifier = "==7.4.0.post2" }, { name = "copier" }, { name = "ipython" }, From afacc3fef70a151fe5163be6d6bfce5503b342a9 Mon Sep 17 00:00:00 2001 From: Oli Wenman Date: Wed, 22 Apr 2026 16:03:46 +0000 Subject: [PATCH 2/8] Exclude blueapi startup scripts from code coverage report --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 8d8613f0..4aafcc56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,6 +92,10 @@ data_file = "/tmp/sm_bluesky.coverage" # Tests are run from installed location, map back to the src directory source = ["src", "**/site-packages/"] +[tool.coverage.report] +# Exclude blueapi client startup scripts from code coverage report +omit = ["*/sm_bluesky/clients/*"] + [tool.tox] skipsdist = true # envs to runs automatically with tox -p From 47bcfd5d0ce850f1019766a8bde462cf744edc81 Mon Sep 17 00:00:00 2001 From: Oli Wenman Date: Wed, 22 Apr 2026 16:04:10 +0000 Subject: [PATCH 3/8] Remove show devices and show plans, have implemented in blueapi client directly --- src/sm_bluesky/clients/blueapi_client.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/sm_bluesky/clients/blueapi_client.py b/src/sm_bluesky/clients/blueapi_client.py index d7997cf9..ba400193 100644 --- a/src/sm_bluesky/clients/blueapi_client.py +++ b/src/sm_bluesky/clients/blueapi_client.py @@ -48,13 +48,3 @@ def _feedback(evt): print(plans) print("Please remember to configure the correct instrument session for bc.") - - -def show_devices(bc: BlueapiClient = bc): - for device in bc.devices: - print(device) - - -def show_plans(bc: BlueapiClient = bc): - for plan in bc.plans: - print(plan) From aefb09e5a2707f4bfe6dc52a3cb58f06516bf7a9 Mon Sep 17 00:00:00 2001 From: Oli Wenman Date: Wed, 22 Apr 2026 16:05:56 +0000 Subject: [PATCH 4/8] Corrected script path doc string --- src/sm_bluesky/clients/blueapi_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm_bluesky/clients/blueapi_client.py b/src/sm_bluesky/clients/blueapi_client.py index ba400193..99a315ce 100644 --- a/src/sm_bluesky/clients/blueapi_client.py +++ b/src/sm_bluesky/clients/blueapi_client.py @@ -1,6 +1,6 @@ """ Start this script by running: -$ python -i src/sm_bluesky/clients/i09/blueapi_client.py +$ python -i src/sm_bluesky/clients/blueapi_client.py """ from os import environ From 6bf75838731129a873609de11ed2dcd557e058ec Mon Sep 17 00:00:00 2001 From: Oli Wenman Date: Wed, 22 Apr 2026 16:08:55 +0000 Subject: [PATCH 5/8] Added more help text --- src/sm_bluesky/clients/blueapi_client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sm_bluesky/clients/blueapi_client.py b/src/sm_bluesky/clients/blueapi_client.py index 99a315ce..ac6b51e6 100644 --- a/src/sm_bluesky/clients/blueapi_client.py +++ b/src/sm_bluesky/clients/blueapi_client.py @@ -24,6 +24,7 @@ ), ) ) +print('Created BlueapiClient "bc" object.') print("Logging in...") bc.login() From a248377cc1944f28c9608f19b8e371e4bdda0fc4 Mon Sep 17 00:00:00 2001 From: Oli Wenman Date: Thu, 23 Apr 2026 08:15:03 +0000 Subject: [PATCH 6/8] Addd name == main check --- src/sm_bluesky/clients/blueapi_client.py | 76 ++++++++++++------------ 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/sm_bluesky/clients/blueapi_client.py b/src/sm_bluesky/clients/blueapi_client.py index ac6b51e6..c10451f3 100644 --- a/src/sm_bluesky/clients/blueapi_client.py +++ b/src/sm_bluesky/clients/blueapi_client.py @@ -9,43 +9,41 @@ from blueapi.config import ApplicationConfig, HttpUrl, RestConfig, StompConfig, TcpUrl from blueapi.core.bluesky_types import DataEvent -BEAMLINE = environ.get("BEAMLINE") -if BEAMLINE is None: - raise RuntimeError("BEAMLINE environment variable not set.") - - -print(f"Starting BlueAPI client for {BEAMLINE}.") -bc = BlueapiClient.from_config( - ApplicationConfig( - api=RestConfig(url=HttpUrl(f"https://{BEAMLINE}-blueapi.diamond.ac.uk")), - stomp=StompConfig( - enabled=True, - url=TcpUrl(f"tcp://{BEAMLINE}-rabbitmq-daq.diamond.ac.uk:61613"), - ), +if __name__ == "__main__": + BEAMLINE = environ.get("BEAMLINE") + if BEAMLINE is None: + raise RuntimeError("BEAMLINE environment variable not set.") + + print(f"Starting BlueAPI client for {BEAMLINE}.") + bc = BlueapiClient.from_config( + ApplicationConfig( + api=RestConfig(url=HttpUrl(f"https://{BEAMLINE}-blueapi.diamond.ac.uk")), + stomp=StompConfig( + enabled=True, + url=TcpUrl(f"tcp://{BEAMLINE}-rabbitmq-daq.diamond.ac.uk:61613"), + ), + ) ) -) -print('Created BlueapiClient "bc" object.') -print("Logging in...") -bc.login() - - -def _feedback(evt): - match evt: - case DataEvent(name="start"): - print("Run started") - case DataEvent(name="stop", doc={"exit_status": status}): - print("Run complete: ", status) - case DataEvent(name="event", doc={"seq_num": point, "data": data}): - print(f" Point {point}: {data}") - - -feedback_id = bc.add_callback(_feedback) -print("Installed feedback.") - -print("\nGetting devices and plans...") -devs = bc.devices -plans = bc.plans -print(devs) -print(plans) - -print("Please remember to configure the correct instrument session for bc.") + print('Created BlueapiClient "bc" object.') + print("Logging in...") + bc.login() + + def _feedback(evt): + match evt: + case DataEvent(name="start"): + print("Run started") + case DataEvent(name="stop", doc={"exit_status": status}): + print("Run complete: ", status) + case DataEvent(name="event", doc={"seq_num": point, "data": data}): + print(f" Point {point}: {data}") + + feedback_id = bc.add_callback(_feedback) + print("Installed feedback.") + + print("\nGetting devices and plans...") + devs = bc.devices + plans = bc.plans + print(devs) + print(plans) + + print("Please remember to configure the correct instrument session for bc.") From dfdb257c86b0be98792372e5f3d5059b2a45678d Mon Sep 17 00:00:00 2001 From: Oli Wenman Date: Tue, 28 Apr 2026 14:30:13 +0000 Subject: [PATCH 7/8] Move to sm_bluesky/scripts/clients --- pyproject.toml | 2 +- src/sm_bluesky/{clients => scripts}/__init__.py | 0 src/sm_bluesky/scripts/clients/__init__.py | 0 src/sm_bluesky/{ => scripts}/clients/blueapi_client.py | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename src/sm_bluesky/{clients => scripts}/__init__.py (100%) create mode 100644 src/sm_bluesky/scripts/clients/__init__.py rename src/sm_bluesky/{ => scripts}/clients/blueapi_client.py (100%) diff --git a/pyproject.toml b/pyproject.toml index 4aafcc56..adcb398f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,7 +94,7 @@ source = ["src", "**/site-packages/"] [tool.coverage.report] # Exclude blueapi client startup scripts from code coverage report -omit = ["*/sm_bluesky/clients/*"] +omit = ["*/sm_bluesky/scripts/clients/*"] [tool.tox] skipsdist = true diff --git a/src/sm_bluesky/clients/__init__.py b/src/sm_bluesky/scripts/__init__.py similarity index 100% rename from src/sm_bluesky/clients/__init__.py rename to src/sm_bluesky/scripts/__init__.py diff --git a/src/sm_bluesky/scripts/clients/__init__.py b/src/sm_bluesky/scripts/clients/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sm_bluesky/clients/blueapi_client.py b/src/sm_bluesky/scripts/clients/blueapi_client.py similarity index 100% rename from src/sm_bluesky/clients/blueapi_client.py rename to src/sm_bluesky/scripts/clients/blueapi_client.py From 851f4677b303ec6b11310578d51143a9dc5e69a7 Mon Sep 17 00:00:00 2001 From: Oli Wenman Date: Wed, 29 Apr 2026 08:20:46 +0000 Subject: [PATCH 8/8] Correct path --- src/sm_bluesky/scripts/clients/blueapi_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm_bluesky/scripts/clients/blueapi_client.py b/src/sm_bluesky/scripts/clients/blueapi_client.py index c10451f3..2c66c068 100644 --- a/src/sm_bluesky/scripts/clients/blueapi_client.py +++ b/src/sm_bluesky/scripts/clients/blueapi_client.py @@ -1,6 +1,6 @@ """ Start this script by running: -$ python -i src/sm_bluesky/clients/blueapi_client.py +$ python -i src/sm_bluesky/scripts/clients/blueapi_client.py """ from os import environ