Skip to main content

Python implementation of LabThings, based on the Flask microframework

Project description

Python LabThings (for Flask)

LabThings ReadTheDocs PyPI Code style: black codecov Riot.im

A thread-based Python implementation of the LabThings API structure, based on the Flask microframework.

Installation

pip install labthings

Quickstart example

This example assumes a PretendSpectrometer class, which already has data and integration_time attributes, as well as an average_data(n) method. LabThings allows you to easily convert this existing instrument control code into a fully documented, standardised web API complete with auto-discovery and automatic background task threading.

#!/usr/bin/env python
import time

from labthings import ActionView, PropertyView, create_app, fields, find_component, op
from labthings.example_components import PretendSpectrometer
from labthings.json import encode_json

"""
Class for our lab component functionality. This could include serial communication,
equipment API calls, network requests, or a "virtual" device as seen here.
"""


"""
Create a view to view and change our integration_time value,
and register is as a Thing property
"""


# Wrap in a semantic annotation to autmatically set schema and args
class DenoiseProperty(PropertyView):
    """Value of integration_time"""

    schema = fields.Int(required=True, minimum=100, maximum=500)
    semtype = "LevelProperty"

    @op.readproperty
    def get(self):
        # When a GET request is made, we'll find our attached component
        my_component = find_component("org.labthings.example.mycomponent")
        return my_component.integration_time

    @op.writeproperty
    def put(self, new_property_value):
        # Find our attached component
        my_component = find_component("org.labthings.example.mycomponent")

        # Apply the new value
        my_component.integration_time = new_property_value

        return my_component.integration_time


"""
Create a view to quickly get some noisy data, and register is as a Thing property
"""


class QuickDataProperty(PropertyView):
    """Show the current data value"""

    # Marshal the response as a list of floats
    schema = fields.List(fields.Float())

    @op.readproperty
    def get(self):
        # Find our attached component
        my_component = find_component("org.labthings.example.mycomponent")
        return my_component.data



"""
Create a view to start an averaged measurement, and register is as a Thing action
"""


class MeasurementAction(ActionView):
    # Expect JSON parameters in the request body.
    # Pass to post function as dictionary argument.
    args = {
        "averages": fields.Integer(
            missing=20, example=20, description="Number of data sets to average over",
        )
    }
    # Marshal the response as a list of numbers
    schema = fields.List(fields.Number)

    # Main function to handle POST requests
    @op.invokeaction
    def post(self, args):
        """Start an averaged measurement"""

        # Find our attached component
        my_component = find_component("org.labthings.example.mycomponent")

        # Get arguments and start a background task
        n_averages = args.get("averages")

        # Return the task information
        return my_component.average_data(n_averages)


# Create LabThings Flask app
app, labthing = create_app(
    __name__,
    title="My Lab Device API",
    description="Test LabThing-based API",
    version="0.1.0",
)

# Attach an instance of our component
# Usually a Python object controlling some piece of hardware
my_spectrometer = PretendSpectrometer()
labthing.add_component(my_spectrometer, "org.labthings.example.mycomponent")


# Add routes for the API views we created
labthing.add_view(DenoiseProperty, "/integration_time")
labthing.add_view(QuickDataProperty, "/quick-data")
labthing.add_view(MeasurementAction, "/actions/measure")


# Start the app
if __name__ == "__main__":
    from labthings import Server

    Server(app).run()

Acknowledgements

Much of the code surrounding default response formatting has been liberally taken from Flask-RESTful. The integrated Marshmallow support was inspired by Flask-Marshmallow and Flask-ApiSpec.

Developer notes

Changelog generation

  • npm install -g conventional-changelog-cli
  • conventional-changelog -r 1 --config ./changelog.config.js -i CHANGELOG.md -s

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

labthings-1.2.2.tar.gz (2.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

labthings-1.2.2-py3-none-any.whl (2.5 MB view details)

Uploaded Python 3

File details

Details for the file labthings-1.2.2.tar.gz.

File metadata

  • Download URL: labthings-1.2.2.tar.gz
  • Upload date:
  • Size: 2.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.4 CPython/3.7.9 Linux/5.4.0-1031-azure

File hashes

Hashes for labthings-1.2.2.tar.gz
Algorithm Hash digest
SHA256 62a8c5bceea25883a7f329a8e19bd95d211d4fe8ac7eb39ee2a2bd51befa4bd5
MD5 4c019f27d3e41b0d52f1a91d62901d72
BLAKE2b-256 86530f5b570506093501f45e2a98f629289bb07684801f722f4965af99d238ad

See more details on using hashes here.

File details

Details for the file labthings-1.2.2-py3-none-any.whl.

File metadata

  • Download URL: labthings-1.2.2-py3-none-any.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.4 CPython/3.7.9 Linux/5.4.0-1031-azure

File hashes

Hashes for labthings-1.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0f4fb76feed5ce9213d471f97700c4b52d9563f940954e1efb644889d3381d2d
MD5 7525c2f5ba48776e67efc01c02c0d4d2
BLAKE2b-256 beceb7dc38e6d54e37262f3db94fe62336ba0f5348f49d02d24c74a83ba70dac

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page