LabThings structure
LabThings is intended to simplify the process of making a piece of hardware available through an HTTP API and documenting that API with Generated documentation.
Server
LabThings is a server-based framework.
The ThingServer creates and manages the Thing instances that represent individual hardware or software units. The functionality of those Things is accessed via HTTP requests, which can be made from a web browser, the command line, or any programming language with an HTTP library.
LabThings-FastAPI is built on top of fastapi, which is a fast, modern HTTP framework. LabThings provides functionality to manage Things and their actions, including:
Initialising, starting up, and shutting down the
Thinginstances, so that hardware is correctly started up and shut down.Managing actions, including making logs and output values available over HTTP.
Managing
Blobinput and output (i.e. binary objects that are best not serialised to JSON).Generating a Thing Description in addition to the OpenAPI documentation produced by
fastapi.Making connections between
Thinginstances as required.
Things
Each unit of hardware (or software) that should be exposed by the server is implemented as a subclass of Thing. A Thing subclass represents a particular type of instrument (whether hardware or software), and its functionality is described using actions and properties, described below. Things don’t have to correspond to separate pieces of hardware: it’s possible (and indeed recommended) to use Thing subclasses for software components, plug-ins, swappable modules, or anything else that needs to add functionality to the server. Things may access each other’s attributes, so you can write a Thing that implements a particular measurement protocol or task, using hardware that’s accessed through other Thing instances on the server. Each Thing is documented by a Thing Description which outlines its features in a higher-level way than OpenAPI.
The attributes of a Thing are made available over HTTP by decorating or marking them with the following functions:
propertymay be used as a decorator analogous to Python’s built-in@property. It can also be used to mark class attributes as variables that should be available over HTTP.settingworks similarly topropertybut it is persisted to disk when the server stops, so the value is remembered.lt.actionis a decorator that makes methods available over HTTP.thing_slottells LabThings to supply an instance of anotherThingat runtime, so yourThingcan make use of it.
Client Code
Client code can be written in any language that supports an HTTP request. However, LabThings FastAPI provides additional functionality that makes writing client code in Python easier. See Using Things for more detail.
ThingClient is a class that wraps up the required HTTP requests into a simpler interface. It can retrieve the Thing Description over HTTP and use it to generate a new object with methods matching each lt.action and properties matching each property.
While the current dynamic implementation of ThingClient can be inspected with functions like help at runtime, it does not work well with static tools like mypy or pyright. In the future, LabThings should be able to generate static client code that works better with autocompletion and type checking.
Data types
LabThings follows fastapi‘s approach of using type hints to define the data types of action parameters and property values. Standard Python types can be used wherever possible, and pydantic will be used in the background to generate JSONSchema definitions as part of the API documentation. More complicated datatypes may be described using pydantic models, which can be used as type hints in action signatures or property definitions.
Binary data that is not easily serialised to JSON (e.g. images, large arrays, or files) may be represented using the Blob datatype. This is described in more detail in Blob input/output.