diff --git a/docs/resources/config.yaml b/docs/resources/config.yaml new file mode 100644 index 000000000..b902011ac --- /dev/null +++ b/docs/resources/config.yaml @@ -0,0 +1,13 @@ +env: + metadata: + instrument: demo + sources: + - kind: deviceManager + module: blueapi.tutorial.devices + - kind: planFunctions + module: dodal.plans + - kind: planFunctions + module: dodal.plan_stubs.wrapped +stomp: + enabled: true + url: tcp://localhost:61613/ diff --git a/pyproject.toml b/pyproject.toml index e3a131e5c..1687c81cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,6 +43,9 @@ license.file = "LICENSE" readme = "README.md" requires-python = ">=3.11" +[project.optional-dependencies] +demo = ["dls-dodal>=1.69.0", "ophyd-async[sim]"] + [dependency-groups] dev = [ "ophyd_async[sim]", @@ -76,7 +79,7 @@ dev = [ "tiled[minimal-server]>=0.2.4", # For system-test of dls.py "respx", "pytest-xdist[psutil]", - "httpx2>=2.5.0" + "httpx2>=2.5.0", ] [project.scripts] diff --git a/src/blueapi/tutorial/__init__.py b/src/blueapi/tutorial/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/blueapi/tutorial/devices.py b/src/blueapi/tutorial/devices.py new file mode 100644 index 000000000..e4466791d --- /dev/null +++ b/src/blueapi/tutorial/devices.py @@ -0,0 +1,31 @@ +from dodal.device_manager import DeviceManager +from ophyd_async import sim + +devices = DeviceManager() + + +@devices.fixture +def path_provider(): + from pathlib import Path + + from ophyd_async.core import AutoIncrementFilenameProvider, StaticPathProvider + + return StaticPathProvider( + AutoIncrementFilenameProvider(base_filename="demo"), + Path("/tmp"), + ) + + +@devices.fixture +def pattern_generator(): + return sim.PatternGenerator() + + +@devices.factory() +def stage(pattern_generator) -> sim.SimStage: + return sim.SimStage(pattern_generator) + + +@devices.factory() +def det(path_provider, pattern_generator) -> sim.SimBlobDetector: + return sim.SimBlobDetector(path_provider, pattern_generator) diff --git a/tests/unit_tests/tutorial/test_devices.py b/tests/unit_tests/tutorial/test_devices.py new file mode 100644 index 000000000..81c80e7f0 --- /dev/null +++ b/tests/unit_tests/tutorial/test_devices.py @@ -0,0 +1,18 @@ +from pathlib import Path + +import pytest + +from blueapi.config import ApplicationConfig, ConfigLoader +from blueapi.core.context import BlueskyContext + + +@pytest.fixture +def context() -> BlueskyContext: + loader = ConfigLoader(ApplicationConfig) + loader.use_values_from_yaml(Path("docs/resources/config.yaml")) + config: ApplicationConfig = loader.load() + return BlueskyContext(configuration=config) + + +def test_devices_loaded_from_module(context): + assert "det", "stage" in context.devices diff --git a/uv.lock b/uv.lock index 5cda625b2..a2c015f12 100644 --- a/uv.lock +++ b/uv.lock @@ -471,6 +471,12 @@ dependencies = [ { name = "uvicorn" }, ] +[package.optional-dependencies] +demo = [ + { name = "dls-dodal" }, + { name = "ophyd-async", extra = ["sim"] }, +] + [package.dev-dependencies] dev = [ { name = "copier" }, @@ -514,6 +520,7 @@ requires-dist = [ { name = "bluesky", extras = ["plotting"], specifier = ">=1.14.0" }, { name = "bluesky-stomp", specifier = ">=0.1.6" }, { name = "click", specifier = ">=8.2.0" }, + { name = "dls-dodal", marker = "extra == 'demo'", specifier = ">=1.69.0" }, { name = "event-model", specifier = "==1.23.1" }, { name = "fastapi", specifier = ">=0.112.0" }, { name = "gitpython" }, @@ -523,6 +530,7 @@ requires-dist = [ { name = "opentelemetry-distro", specifier = ">=0.48b0" }, { name = "opentelemetry-instrumentation-fastapi", specifier = ">=0.48b0" }, { name = "ophyd-async", specifier = ">=0.13.5" }, + { name = "ophyd-async", extras = ["sim"], marker = "extra == 'demo'" }, { name = "pydantic", specifier = ">=2.0" }, { name = "pydantic-settings" }, { name = "pyjwt", extras = ["crypto"] }, @@ -533,6 +541,7 @@ requires-dist = [ { name = "tomlkit" }, { name = "uvicorn" }, ] +provides-extras = ["demo"] [package.metadata.requires-dev] dev = [