labthings_fastapi.thing

The Thing class enables most of the functionality of this library, and is the way in to most of its features. In the future, we might support a stub version of the class in a separate package, so that instrument control libraries can be LabThings compatible without a hard dependency on LabThings. But that is something we will do in the future…

Module Contents

Classes

Thing

Represents a Thing, as defined by the Web of Things standard.

API

class labthings_fastapi.thing.Thing

Represents a Thing, as defined by the Web of Things standard.

This class should encapsulate the code that runs a piece of hardware, or provides a particular function - it will correspond to a path on the server, and a Thing Description document.

Your Thing should be a subclass of Thing - note that we don’t define __init__ so you are free to initialise as you like and don’t need to call super().__init__.

Subclassing Notes

  • __init__: You should accept any arguments you need to configure the Thing in __init__. Don’t initialise any hardware at this time, as your Thing may be instantiated quite early, or even at import time.

  • __enter__(self) and __exit__(self, exc_t, exc_v, exc_tb) are where you should start and stop communications with the hardware. This is Python’s standard “context manager” protocol. The arguments of __exit__ will be None unless an exception has occurred. You should be safe to ignore them, and just include code that will close down your hardware. It’s equivalent to a finally: block.

  • Properties and Actions are defined using decorators: the @thing_action decorator declares a method to be an action, which will run when it’s triggered, and the @thing_property decorator (or PropertyDescriptor descriptor) does the same for a property. See the documentation on those functions for more detail.

  • title will be used in various places as the human-readable name of your Thing, so it makes sense to set this in a subclass.

There are various LabThings methods that you should avoid overriding unless you know what you are doing: anything not mentioned above that’s defined in Thing is probably best left along. They may in time be collected together into a single object to avoid namespace clashes.

title: str

None

_labthings_blocking_portal: Optional[anyio.from_thread.BlockingPortal]

None

path: Optional[str]

None

async __aenter__()

Context management is used to set up/close the thing.

As things (currently) do everything with threaded code, we define async aenter and aexit wrappers to call the synchronous code, if it exists.

async __aexit__(exc_t, exc_v, exc_tb)

Wrap context management functions, if they exist.

See aenter docs for more details.

attach_to_server(server: labthings_fastapi.server.ThingServer, path: str)

Add HTTP handlers to an app for all Interaction Affordances

_labthings_thing_settings: Optional[labthings_fastapi.thing_settings.ThingSettings]

None

property thing_settings: labthings_fastapi.thing_settings.ThingSettings

A dictionary that can be used to persist settings between runs

_labthings_thing_state: Optional[dict]

None

property thing_state: collections.abc.Mapping

Return a dictionary summarising our current state

This is intended to be an easy way to collect metadata from a Thing that summarises its state. It might be used, for example, to record metadata along with each reading/image/etc. when an instrument is saving data.

It’s best to populate this automatically so it can always be accessed. If it requires calls e.g. to a serial instrument, bear in mind it may be called quite often and shouldn’t take too long.

Some measure of cacheing here is a nice aim for the future, but not yet implemented.

validate_thing_description()

Raise an exception if the thing description is not valid

_cached_thing_description: Optional[tuple[Optional[str], Optional[str], labthings_fastapi.thing_description.model.ThingDescription]]

None

thing_description(path: Optional[str] = None, base: Optional[str] = None) labthings_fastapi.thing_description.model.ThingDescription

A w3c Thing Description representing this thing

The w3c Web of Things working group defined a standard representation of a Thing, which provides a high-level description of the actions, properties, and events that it exposes. This endpoint delivers a JSON representation of the Thing Description for this Thing.

thing_description_dict(path: Optional[str] = None, base: Optional[str] = None) dict

A w3c Thing Description representing this thing, as a simple dict

The w3c Web of Things working group defined a standard representation of a Thing, which provides a high-level description of the actions, properties, and events that it exposes. This endpoint delivers a JSON representation of the Thing Description for this Thing.

observe_property(property_name: str, stream: anyio.abc.ObjectSendStream)

Register a stream to receive property change notifications

observe_action(action_name: str, stream: anyio.abc.ObjectSendStream)

Register a stream to receive action status change notifications