Skip to content

Commit fa0155b

Browse files
authored
Merge branch 'main' into token-exchange
2 parents f87bedd + e2fd3f0 commit fa0155b

9 files changed

Lines changed: 48 additions & 11 deletions

File tree

‎.github/workflows/pr.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ jobs:
1111
- name: PR Conventional Commit Validation
1212
uses: ytanikin/pr-conventional-commits@1.5.1
1313
with:
14-
task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert"]'
14+
task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert", "depr"]'
1515
add_label: 'false'

‎docs/explanations/api-version.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# API Version
22

3-
Blueapi has [released versions](https://github.com/DiamondLightSource/blueapi/releases) that are complaint with [semantic versioning](https://semver.org/) to make updating/rolling back as easy as possible. Blueapi's [REST API](../reference/rest-spec.md) is versioned separately to the main application, since not all changes will affect it. The idea is that a change in the REST API version is a signal to client developers that they may need to do some work to update.
3+
Blueapi has [released versions](https://github.com/DiamondLightSource/blueapi/releases) that are compliant with [semantic versioning](https://semver.org/) to make updating/rolling back as easy as possible. Blueapi's [REST API](../reference/rest-spec.md) is versioned separately to the main application, since not all changes will affect it. The idea is that a change in the REST API version is a signal to client developers that they may need to do some work to update.
44

55
If you are a developer contributing a PR, there is a unit test that will fail if the REST API has changed in your PR but the version defined in the code, [](#REST_API_VERSION), has not been updated. You should update the version for _any_ change to the API at all, whether it's a major, minor or patch update is to be determined by the developer(s) and the reviewer(s) involved. _Do not_ update [`docs/reference/openapi.yaml`](../reference/openapi.yaml), it is checked against `main` in CI.

‎docs/explanations/events.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ a plan has started, finished, paused, errored etc. See the example below:
1616
![sequence of event emission compared to plan start/finish, in a complicated case](../images/bluesky-events.png)
1717

1818
Note the gap between the start of the plan and the issue of the first [`run start document`](https://blueskyproject.io/event-model/main/user/explanations/data-model.html#run-start-document), and the similar gap
19-
for the stop document vs end of the plan, thsse are typically used for setup and cleanup.
19+
for the stop document vs end of the plan, these are typically used for setup and cleanup.
2020
Also note that a plan can produce an arbitrary number of runs. This decoupling is fine in an IPython terminal
2121
because a human user can see when a plan has started, can see when it's finished and can see which runs are
2222
associated with which plans.
2323

2424
## New Events
2525

26-
For the case of automation, we introduce a new set of events outside of the event model, specifically
26+
For the case of automation, we introduce a new set of events outside the event model, specifically
2727
pertaining to the running of the plan and state of the `RunEngine`. At a minimum, an event is emitted
2828
every time the engine:
2929

‎src/blueapi/core/context.py‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,18 +220,43 @@ def with_config(self, config: EnvironmentConfig) -> None:
220220

221221
match source:
222222
case PlanSource():
223+
LOGGER.info("Including plans from %s", source.module)
223224
self.with_plan_module(mod)
224225
case DeviceSource():
226+
LOGGER.info("Including devices from %s", source.module)
227+
LOGGER.warning(
228+
"'devices' environment kind is deprecated - please convert "
229+
"configuration to use deviceManager"
230+
)
225231
self.with_device_module(mod)
226232
case DodalSource(mock=mock):
233+
LOGGER.info(
234+
"Including devices from 'dodal' source %s", source.module
235+
)
236+
LOGGER.warning(
237+
"'dodal' environment kind is deprecated - please convert "
238+
"configuration to use deviceManager"
239+
)
227240
self.with_dodal_module(mod, mock=mock)
228241
case DeviceManagerSource(mock=mock, name=name):
242+
LOGGER.info(
243+
"Including devices from 'deviceManager' source %s:%s",
244+
source.module,
245+
name,
246+
)
229247
manager = getattr(mod, name)
230248
if not isinstance(manager, DeviceManager):
231249
raise ValueError(
232250
f"{name} in module {mod} is not a device manager"
233251
)
234252
self.with_device_manager(manager, mock)
253+
if not self.devices:
254+
LOGGER.warning(
255+
"Context had no devices after loading environment - are all modules "
256+
"included and marked with the correct 'kind'?"
257+
)
258+
if not self.plans:
259+
LOGGER.warning("Context had no plans registered after loading environment")
235260

236261
def with_plan_module(self, module: ModuleType) -> None:
237262
"""
@@ -284,6 +309,15 @@ def with_device_manager(self, manager: DeviceManager, mock: bool = False):
284309
f"{len(errs)} errors while connecting devices",
285310
exc_info=NotConnectedError(errs),
286311
)
312+
if not (
313+
build_result.devices
314+
or build_result.build_errors
315+
or build_result.connection_errors
316+
):
317+
LOGGER.warning("Device manager did not build any devices")
318+
319+
utils.report_successful_devices(build_result.devices, mock)
320+
287321
return build_result.devices, {
288322
**build_result.build_errors,
289323
**build_result.connection_errors,
@@ -322,6 +356,8 @@ def with_dodal_module(
322356
f"{len(exceptions)} exceptions occurred while instantiating devices"
323357
)
324358
LOGGER.exception(NotConnectedError(exceptions))
359+
elif not devices:
360+
LOGGER.warning("No devices were loaded from dodal module %s", module)
325361
return devices, exceptions
326362

327363
def register_plan(self, plan: PlanGenerator) -> PlanGenerator:

‎src/blueapi/log.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def set_up_stream_handler(
9090
Args:
9191
logger: Logger to attach handler to
9292
logging_config: LoggingConfig
93+
filters: list of filters
9394
"""
9495
stream_handler = logging.StreamHandler()
9596
stream_handler.setLevel(logging_config.level)
@@ -137,7 +138,7 @@ class IBMColorBlindSafeColors(enum.Enum):
137138

138139

139140
class ColorFormatter(logging.Formatter):
140-
"""Colors level_name of log using IBM color blind safe palette."""
141+
"""Colors level_name of log using IBM color-blind safe palette."""
141142

142143
def _level_colour(self, level_no: int) -> tuple[int, int, int] | None:
143144
match level_no:

‎src/blueapi/service/main.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,6 @@ def get_tasks(
366366
Retrieve tasks based on their status.
367367
The status of a newly created task is 'unstarted'.
368368
"""
369-
tasks = []
370369
if task_status:
371370
add_span_attributes({"status": task_status})
372371
try:

‎src/blueapi/utils/__init__.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .base_model import BlueapiBaseModel, BlueapiModelConfig, BlueapiPlanModelConfig
2-
from .connect_devices import connect_devices
2+
from .connect_devices import connect_devices, report_successful_devices
33
from .file_permissions import get_owner_gid, is_sgid_set
44
from .invalid_config_error import InvalidConfigError
55
from .modules import is_function_sourced_from_module, load_module_all
@@ -17,6 +17,7 @@
1717
"InvalidConfigError",
1818
"NumtrackerClient",
1919
"connect_devices",
20+
"report_successful_devices",
2021
"is_sgid_set",
2122
"get_owner_gid",
2223
"is_function_sourced_from_module",

‎src/blueapi/utils/connect_devices.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
LOGGER = logging.getLogger(__name__)
1616

1717

18-
def _report_successful_devices(
18+
def report_successful_devices(
1919
devices: Mapping[str, AnyDevice],
2020
sim_backend: bool,
2121
) -> None:
@@ -86,14 +86,14 @@ def is_simulated_device(name, factory, **kwargs):
8686
real_devices, exceptions = _establish_device_connections(
8787
run_engine, real_devices, False
8888
)
89-
_report_successful_devices(real_devices, False)
89+
report_successful_devices(real_devices, False)
9090
exception_map |= exceptions
9191
if len(sim_devices) > 0:
9292
sim_devices, exceptions = _establish_device_connections(
9393
run_engine,
9494
sim_devices, # type: ignore
9595
True,
9696
)
97-
_report_successful_devices(sim_devices, True)
97+
report_successful_devices(sim_devices, True)
9898
exception_map |= exceptions
9999
return exception_map

‎src/blueapi/worker/task_worker.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ def get_tasks_by_status(self, status: TaskStatusEnum) -> list[TrackableTask]:
213213
"""
214214
Retrieve a list of tasks based on their status.
215215
Args:
216-
TaskStatusEnum: The status to filter tasks by.
216+
status TaskStatusEnum: The status to filter tasks by.
217217
Returns:
218218
list[TrackableTask]: A list of tasks that match the given status.
219219
"""

0 commit comments

Comments
 (0)