Quick start

You can install labthings-fastapi using pip. We recommend you create a virtual environment, for example:

python -m venv .venv --prompt labthings
source .venv/bin/activate  # or .venv/Scripts/activate on Windows

then install labthings with:

pip install labthings-fastapi

To define a simple example Thing, paste the following into a Python file, counter.py:

"""An example Thing that implements a counter."""

import time
import labthings_fastapi as lt


class TestThing(lt.Thing):
    """A test thing with a counter property and a couple of actions."""

    @lt.action
    def increment_counter(self) -> None:
        """Increment the counter property.

        This action doesn't do very much - all it does, in fact,
        is increment the counter (which may be read using the
        `counter` property).
        """
        self.counter += 1

    @lt.action
    def slowly_increase_counter(self) -> None:
        """Increment the counter slowly over a minute."""
        for _i in range(60):
            time.sleep(1)
            self.increment_counter()

    counter: int = lt.property(default=0, readonly=True)
    "A pointless counter."


if __name__ == "__main__":
    import uvicorn

    server = lt.ThingServer.from_things({"counter": TestThing})

    # We run the server using `uvicorn`:
    uvicorn.run(server.app, port=5000, ws="websockets-sansio")

counter.py defines the TestThing class, and then runs a LabThings server in its __name__ == "__main__" block. This means we should be able to run the server with:

python counter.py

Visiting http://localhost:5000/counter/ will show the thing description, and you can interact with the actions and properties using the Swagger UI at http://localhost:5000/docs/.

You can also interact with it from another Python instance, for example by running:

"""Client code that interacts with the counter Thing over HTTP."""

from labthings_fastapi import ThingClient

counter = ThingClient.from_url("http://localhost:5000/counter/")

v = counter.counter
print(f"The counter value was {v}")

counter.increment_counter()

v = counter.counter
print(f"After incrementing, the counter value was {v}")

It’s best to write Thing subclasses in Python packages that can be imported. This makes them easier to reuse and distribute, and also allows us to run a LabThings server from the command line, configured by a configuration file. An example config file is below:

{
    "things": {
        "example": "labthings_fastapi.example_things:MyThing"
    }
}

Paste this into example_config.json and then run a server using:

labthings-server -c example_config.json

Bear in mind that this won’t work if counter.py above is still running - both will try to use port 5000.

As before, you can visit http://localhost:5000/docs or http://localhost:5000/example/ to see the OpenAPI docs or Thing Description, and you can use the Python client module with the second of those URLs.