labthings_fastapi.descriptors.action

Define an object to represent an Action, as a descriptor.

Attributes

ACTION_POST_NOTICE

ACTION_GET_DESCRIPTION

Classes

ActionDescriptor

Wrap actions to enable them to be run over HTTP.

Module Contents

labthings_fastapi.descriptors.action.ACTION_POST_NOTICE = Multiline-String
Show Value
"""
## Important note

This `POST` request starts an Action, i.e. the server will do something
that may continue after the HTTP request has been responded to.  The
response will always be an ActionInvocation object, that details the current
status of the action and provides an interface to poll for completion.

If the action completes within a specified timeout, we will return
an HTTP status code of `200` and the return value will include any
output from the action.  If it does not complete, we will return a
`201` response code, and the action's endpoint may be polled to follow
its progress.
"""
labthings_fastapi.descriptors.action.ACTION_GET_DESCRIPTION = Multiline-String
Show Value
"""
This will include times and input values, as well as output values for
actions that have completed. These actions will also show up under the
`action_invocations` endpoint, and can also be retrieved individually
using the link included in each action.
"""
class labthings_fastapi.descriptors.action.ActionDescriptor(func: Callable, response_timeout: float = 1, retention_time: float = 300)

Wrap actions to enable them to be run over HTTP.

This class is responsible for generating the action description for the Thing Description and creating the function that responds to POST requests to invoke the action.

Note

Descriptors are instantiated once per class. This means that we cannot assume there is only one action corresponding to this descriptor: there may be multiple Thing instances with the same descriptor. That is why the host Thing must be passed to many functions as an argument, and why observers, for example, must be keyed by the Thing rather than kept as a property of self.

Create a new action descriptor.

The action descriptor wraps a method of a Thing. It may still be called from Python in the same way, but it will also be added to the HTTP API and automatic documentation.

Parameters:
  • func – is the method that will be run when the action is called.

  • response_timeout – is how long we should wait before returning a response to the client. This is not currently used, as we always return immediately with a 201 code. In the future, it may set a default time to wait before responding. If the action finishes before we respond, we will be able to return the completed action and its output. If the action is still running, we return a 201 code and data enabling the client to poll to find out the status of the action.

  • retention_time – how long, in seconds, the action should be kept for after it has completed.

func
response_timeout = 1
retention_time = 300
dependency_params = []
input_model
output_model
invocation_model = None
__get__(obj: Literal[None], type=None) ActionDescriptor
__get__(obj: labthings_fastapi.thing.Thing, type=None) Callable

Return the function, bound to an object as for a normal method.

This currently doesn’t validate the arguments, though it may do so in future. In its present form, this is equivalent to a regular Python method, i.e. all we do is supply the first argument, self.

If obj is None, the descriptor is returned, so we can get the descriptor conveniently as an attribute of the class.

Parameters:
  • obj – the Thing to which we are attached. This will be the first argument supplied to the function wrapped by this descriptor.

  • type – the class of the Thing to which we are attached. If the descriptor is accessed via the class it is returned directly.

Returns:

the action function, bound to obj (when accessed via an instance), or the descriptor (accessed via the class).

property name

The name of the wrapped function.

property title

A human-readable title.

property description

A description of the action.

_observers_set(obj: labthings_fastapi.thing.Thing) weakref.WeakSet

Return a set used to notify changes.

Note that we need to supply the Thing we are looking at, as in general there may be more than one object of the same type, and descriptor instances are shared between all instances of their class.

Parameters:

obj – The Thing on which the action is being observed.

Returns:

a weak set of callables to notify on changes to the action. This is used by websocket endpoints.

emit_changed_event(obj: labthings_fastapi.thing.Thing, status: str)

Notify subscribers that the action status has changed.

This function is run from within the Invocation thread that is created when an action is called. It must be run from a thread as it is communicating with the event loop via an asyncio blocking portal. Async code must not use the blocking portal as it can deadlock the event loop.

Parameters:
  • obj – The Thing on which the action is being observed.

  • status – The status of the action, to be sent to observers.

Raises:

NotConnectedToServerError – if the Thing calling the action is not connected to a server with a running event loop.

async emit_changed_event_async(obj: labthings_fastapi.thing.Thing, value: Any) None

Notify subscribers that the action status has changed.

This is an async function that must be run in the anyio event loop. It will send messages to each observer to notify them that something has changed.

Parameters:
  • obj – The Thing on which the action is defined. ActionDescriptor objects are unique to the class, but there may be more than one Thing attached to a server with the same class. We use obj to look up the observers of the current Thing.

  • value – The action status to communicate to the observers.

add_to_fastapi(app: fastapi.FastAPI, thing: labthings_fastapi.thing.Thing) None

Add this action to a FastAPI app, bound to a particular Thing.

This function creates two functions to handle GET and POST requests to the action’s endpoint, and adds them to the fastapi.FastAPI application.

Parameters:
  • app – The fastapi.FastAPI app to add the endpoint to.

  • thing – The Thing to which the action is attached. Bear in mind that the descriptor may be used by more than one Thing, so this can’t be a property of the descriptor.

action_affordance(thing: labthings_fastapi.thing.Thing, path: str | None = None) labthings_fastapi.thing_description._model.ActionAffordance

Represent the property in a Thing Description.

This function describes the Action in Thing Description format.

Parameters:
  • thing – The Thing to which the action is attached.

  • path – The prefix applied to all endpoints associated with the Thing. This is the URL for the Thing Description. If it is omitted, we use the path property of the thing.

Returns:

An ActionAffordance describing this action.