labthings_fastapi.thing
A class to represent hardware or software Things.
The Thing class enables most of the functionality of this library,
and is the way in to most of its features. See LabThings structure
for how it fits with the rest of the library.
Classes
Represents a Thing, as defined by the Web of Things standard. |
Module Contents
- class labthings_fastapi.thing.Thing(thing_server_interface: labthings_fastapi.thing_server_interface.ThingServerInterface)
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.
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. You must make sure to callsuper().__init__(thing_server_interface).__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 “context manager” protocol. The arguments of__exit__will beNoneexcept after errors. You should be safe to ignore them, and just include code that will close down your hardware, which is equivalent to afinally:block.Properties and Actions are defined using decorators: the
@lt.actiondecorator declares a method to be an action, which will run when it’s triggered, and the@propertydecorator does the same for a property.Properties may also be defined using dataclass-style syntax, if they do not need getter and setter functions.
See the documentation on those functions for more detail.
titlewill 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
Thingis probably best left alone.Initialise a Thing.
The most important function of
__init__is attaching the thing_server_interface, and setting the path. Note thatThinginstances are usually created by aThingServerand not instantiated directly: if you do make aThingdirectly, you will need to supply aThingServerInterfacethat is connected to aThingServeror a suitable mock object.- param thing_server_interface:
The interface to the server that is hosting this Thing. It will be supplied when the
Thingis instantiated by theThingServeror bycreate_thing_without_serverwhich generates a mock interface.
- _class_settings: labthings_fastapi.thing_class_settings.ThingClassSettings
A dictionary of settings that affect how the Thing subclass works.
Valid keys are listed below:
validate_properties_on_setboolIf this key is set to
True, property values will be validated when they are set by Python code, as well as when they are set over HTTP. Currently, the default behaviour is only to validate values sent over HTTP, not set directly in Python. It is likely that validation in both cases will happen by default in a future release.
Note
Class settings must not be changed after the class is defined.
- _thing_server_interface: labthings_fastapi.thing_server_interface.ThingServerInterface
Provide access to features of the server that this
Thingis attached to.
- classmethod __init_subclass__(**kwargs: Any) None
Validate the class settings.
- Parameters:
**kwargs – are passed to the superclass.
- property logger: logging.Logger
A logger, named after this Thing.
- async __aenter__() Self
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.- Returns:
this object.
- async __aexit__(exc_t: Any | None, exc_v: Any | None, exc_tb: Any) None
Wrap context management functions, if they exist.
See
__aenter__for more details.- Parameters:
exc_t – The type of the exception, or
None.exc_v – The exception that occurred, or
None.exc_tb – The traceback for the exception, or
None.
- attach_to_server(server: labthings_fastapi.server.ThingServer) None
Attach this thing to the server.
Things need to be attached to a server before use to function correctly.
- Parameters:
server – The server to attach this Thing to.
Attaching the
Thingto aThingServerallows theThingto start actions, load its settings from the correct place, and create HTTP endpoints to allow it to be accessed from the HTTP API.We create HTTP endpoints for all Interaction Affordances on the
Thing, as well as anyEndpointDescriptordescriptors.
- _read_settings_file() collections.abc.Mapping[str, Any] | None
Read the settings file and return a mapping of saved settings or None.
This function handles reading the settings from the disk. It is designed to be called by
load_settings. Any exceptions caused by file handling or file corruption are caught and logged as warnings.- Returns:
A Mapping of setting name to setting value, or None if no settings could be read from file.
- load_settings() None
Load settings from json.
Read the JSON file and use it to populate settings.
Note
Settings are loaded when the Thing is added to a server, so they will not be available while the
__init__method is run.Note that no notifications will be triggered when the settings are set, so if action is needed (e.g. updating hardware with the loaded settings) it should be taken in
__enter__.
- save_settings() None
Save settings to JSON.
This is called whenever a setting is updated. All settings are written to the settings file every time.
- properties: labthings_fastapi.base_descriptor.OptionallyBoundDescriptor[Thing, labthings_fastapi.properties.PropertyCollection]
Access to metadata and functions of this
Thing‘s properties.propertiesis a mapping of names toPropertyInfoobjects, which allows convenient access to the metadata related to its properties. Note that this includes settings, as they are a subclass of properties.
- settings: labthings_fastapi.base_descriptor.OptionallyBoundDescriptor[Thing, labthings_fastapi.properties.SettingCollection]
Access to settings-related metadata and functions.
settingsis a mapping of names toSettingInfoobjects that allows convenient access to metadata of the settings of thisThing.
- actions: labthings_fastapi.base_descriptor.OptionallyBoundDescriptor[Thing, labthings_fastapi.actions.ActionCollection]
Access to metadata for the actions of this
Thing.actionsis a mapping of names toActionInfoobjects that allows convenient access to metadata of each action.
- 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 caching here is a nice aim for the future, but not yet implemented.
- _cached_thing_description: tuple[str | None, str | None, labthings_fastapi.thing_description._model.ThingDescription] | None = None
- thing_description(path: str | None = None, base: str | None = None) labthings_fastapi.thing_description._model.ThingDescription
Generate 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.
- Parameters:
path – the URL pointing to this Thing.
base – the base URL for all URLs in the thing description.
- Returns:
a Thing Description.
- thing_description_dict(path: str | None = None, base: str | None = None) dict
Describe this Thing with a Thing Description as a simple dict.
See
thing_description. This function converts the return value of that function into a simple dictionary.- Parameters:
path – the URL pointing to this Thing.
base – the base URL for all URLs in the thing description.
- Returns:
a Thing Description.
- get_current_invocation_logs() list[logging.LogRecord]
Get the log records for an on going action.
This is useful if an action wishes to save its logs alongside any data.
Note that only the last 1000 logs are returned so for long running tasks that log frequently this may want to be read periodically.
This will error if it is called outside an action invocation.
- Returns:
a list of all logs from this action.
- Raises:
RuntimeError – If the server cannot be retrieved. This should never happen.