bluesky / bluesky-queueserver

Server for queueing plans
https://blueskyproject.io/bluesky-queueserver/
BSD 3-Clause "New" or "Revised" License
12 stars 22 forks source link

Support for in-header annotations of devices and callables #288

Closed dmgav closed 1 year ago

dmgav commented 1 year ago

Description

Add new 'default' types for use in plan descriptions: __READABLE__, __MOVABLE__, __FLYABLE__ and __CALLABLE__. The __READABLE__, __MOVABLE__ and __FLYABLE__ types are handled by the server identically to the __DEVICE__ type: the type is treated as str for parameter validation, then all the strings passed with the parameter value (elements of a list, values of a dictionary, etc.) are converted to device objects from the list of allowed devices. The strings that do not match device names from the list of allowed devices are passed to the plan as strings (and if those are expected to be device object, the plan fails during execution). Proper validation of parameters based of the list of all allowed devices or lists of readable, movable or flyable subsets of the list could be implemented in the future if requested.

The server can identify the following device types in annotations included in plan headers: bluesky.protocols.Readable, bluesky.protocols.Movable, bluesky.protocols.Flyable. Those types are replaced by the default Queue Server types __READABLE__, __MOVABLE__ and __FLYABLE__. For example, in the following startup code

from typing import List
from bluesky.protocols import Readable, Movable

def plan1(detectors: List[Readable]):
    ...

def plan2(motor: Movable):
    ...

the server assigns the parameter detectors type typing.List[__READABLE__] and the parameter motor type __MOVABLE__.

Similarly, __CALLABLE__ type is treated as str during parameter validation. All parameter values that have type str and match the rules for python variables or dot-separated python variables (e.g. methods of a class), are converted to the respective callable objects. If no respective object is found in namespace, parameter values are passed to the plan as strings. Also, there is no type checking performed on objects, so the plan may still fail if the object is not a callable or a callable with non-matching signature. The server can recognize collections.abc.Callable or deprecated typing.Callable with or without parameters in plan signatures and replace it with __CALLABLE__ in plan description.

When finished, this PR is expected to enable completion of https://github.com/bluesky/bluesky/pull/1600

Motivation and Context

Summary of Changes for Release Notes

Fixed

Added

Changed

Removed

How Has This Been Tested?

Unit tests were added.

tangkong commented 1 year ago

Super excited to see this! Coming from someone who has rather little experience with bluesky Protocols, is there a natural hint a combination of these types? (something that's both Movable and Readable for example).

dmgav commented 1 year ago

@tangkong It is always possible to define union of the protocols. But practically the movable devices are also readable. The flyable devices may not be readable or movable. The Queue Server identifies a device as being readable or flyable, and it seems to work: https://github.com/bluesky/bluesky-queueserver/blob/9974c638fb4e7ac911f37f8b1edf3bae06e04ccf/bluesky_queueserver/manager/profile_ops.py#L695-L701