diff --git a/src/blueapi/controller/__init__.py b/src/blueapi/controller/__init__.py new file mode 100644 index 000000000..271715776 --- /dev/null +++ b/src/blueapi/controller/__init__.py @@ -0,0 +1,5 @@ +from .base import BlueskyControllerBase +from .context import BlueskyContext +from .controller import BlueskyController + +__all__ = ["BlueskyControllerBase", "BlueskyController", "BlueskyContext"] diff --git a/src/blueapi/controller/base.py b/src/blueapi/controller/base.py new file mode 100644 index 000000000..fccb0ef23 --- /dev/null +++ b/src/blueapi/controller/base.py @@ -0,0 +1,44 @@ +from abc import ABC, abstractmethod +from typing import Any, Mapping + +from blueapi.core import Ability, Plan + + +class BlueskyControllerBase(ABC): + """ + Object to control Bluesky, bridge between API and worker + """ + + @abstractmethod + async def run_workers(self) -> None: + ... + + @abstractmethod + async def run_plan(self, __name: str, __params: Mapping[str, Any]) -> None: + """ + Run a named plan with parameters + + Args: + __name (str): The name of the plan to run + __params (Mapping[str, Any]): The parameters for the plan in + deserialized form + """ + + ... + + @property + @abstractmethod + def plans(self) -> Mapping[str, Plan]: + """ + Get a all plans that can be run + + Returns: + Mapping[str, Plan]: Mapping of plans for quick lookup by name + """ + + ... + + @property + @abstractmethod + def abilities(self) -> Mapping[str, Ability]: + ... diff --git a/src/blueapi/core/context.py b/src/blueapi/controller/context.py similarity index 83% rename from src/blueapi/core/context.py rename to src/blueapi/controller/context.py index b82e8758b..dc4b9828d 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/controller/context.py @@ -3,10 +3,7 @@ from bluesky.protocols import Flyable, Readable -from .bluesky_types import Ability, Plan, PlanGenerator -from .schema import schema_for_func - -AbilityRegistry = Dict[str, Ability] +from blueapi.core import Ability, Plan, PlanGenerator, schema_for_func @dataclass @@ -16,7 +13,7 @@ class BlueskyContext: """ plans: Dict[str, Plan] = field(default_factory=dict) - abilities: AbilityRegistry = field(default_factory=dict) + abilities: Dict[str, Ability] = field(default_factory=dict) plan_functions: Dict[str, PlanGenerator] = field(default_factory=dict) def plan(self, plan: PlanGenerator) -> PlanGenerator: diff --git a/src/blueapi/core/controller.py b/src/blueapi/controller/controller.py similarity index 63% rename from src/blueapi/core/controller.py rename to src/blueapi/controller/controller.py index b0958c745..bc713c454 100644 --- a/src/blueapi/core/controller.py +++ b/src/blueapi/controller/controller.py @@ -1,10 +1,15 @@ import asyncio import logging -from abc import ABC, abstractmethod -from typing import Any, AsyncIterable, Awaitable, Callable, Mapping, Optional +from typing import Any, AsyncIterable, Mapping, Optional from bluesky import RunEngine +from blueapi.core import ( + Ability, + Plan, + create_bluesky_protocol_conversions, + nested_deserialize_with_overrides, +) from blueapi.utils import async_events, concurrent_future_to_aio_future from blueapi.worker import ( RunEngineWorker, @@ -14,58 +19,12 @@ run_worker_in_own_thread, ) -from .bluesky_types import Ability, DataEvent, Plan, StatusEvent +from .base import BlueskyControllerBase from .context import BlueskyContext -from .device_lookup import create_bluesky_protocol_conversions -from .schema import nested_deserialize_with_overrides LOGGER = logging.getLogger(__name__) -class BlueskyControllerBase(ABC): - """ - Object to control Bluesky, bridge between API and worker - """ - - @abstractmethod - async def run_workers(self) -> None: - ... - - @abstractmethod - async def run_plan(self, __name: str, __params: Mapping[str, Any]) -> None: - """ - Run a named plan with parameters - - Args: - __name (str): The name of the plan to run - __params (Mapping[str, Any]): The parameters for the plan in - deserialized form - """ - - ... - - @abstractmethod - async def worker_events(self) -> AsyncIterable[WorkerEvent]: - ... - - @property - @abstractmethod - def plans(self) -> Mapping[str, Plan]: - """ - Get a all plans that can be run - - Returns: - Mapping[str, Plan]: Mapping of plans for quick lookup by name - """ - - ... - - @property - @abstractmethod - def abilities(self) -> Mapping[str, Ability]: - ... - - class BlueskyController(BlueskyControllerBase): """ Default implementation of BlueskyControllerBase diff --git a/src/blueapi/core/__init__.py b/src/blueapi/core/__init__.py index 7c5109d07..c9e1ea7dc 100644 --- a/src/blueapi/core/__init__.py +++ b/src/blueapi/core/__init__.py @@ -1,17 +1,16 @@ from .bluesky_types import BLUESKY_PROTOCOLS, Ability, Plan, PlanGenerator -from .context import Ability, AbilityRegistry, BlueskyContext -from .controller import BlueskyController, BlueskyControllerBase +from .device_lookup import create_bluesky_protocol_conversions from .event import EventStream, EventStreamBase +from .schema import nested_deserialize_with_overrides, schema_for_func __all__ = [ "Plan", "PlanGenerator", - "BlueskyControllerBase", - "BlueskyController", - "BlueskyContext", - "AbilityRegistry", "Ability", "BLUESKY_PROTOCOLS", "EventStreamBase", "EventStream", + "schema_for_func", + "nested_deserialize_with_overrides", + "create_bluesky_protocol_conversions", ] diff --git a/src/blueapi/example/server/app.py b/src/blueapi/example/server/app.py index d82e968c1..f1aace3cd 100644 --- a/src/blueapi/example/server/app.py +++ b/src/blueapi/example/server/app.py @@ -11,13 +11,8 @@ from fastapi import FastAPI, Request, WebSocket from ophyd.sim import Syn2DGauss, SynAxis -from blueapi.core import ( - BLUESKY_PROTOCOLS, - Ability, - BlueskyContext, - BlueskyController, - Plan, -) +from blueapi.controller import BlueskyContext, BlueskyController +from blueapi.core import BLUESKY_PROTOCOLS, Ability, Plan ctx = BlueskyContext() logging.basicConfig(level=logging.INFO)