Merge remote-tracking branch 'origin/master' into v2.1.0-dev
This commit is contained in:
commit
6476778673
13 changed files with 142 additions and 41 deletions
|
|
@ -0,0 +1,41 @@
|
|||
from labthings.server.extensions import BaseExtension
|
||||
from labthings.server.find import find_component
|
||||
|
||||
|
||||
# Create the extension class
|
||||
class MyExtension(BaseExtension):
|
||||
def __init__(self):
|
||||
|
||||
# Create some instance variable
|
||||
self.state_variable = "An example of a persistant instance variable"
|
||||
|
||||
# Superclass init function
|
||||
super().__init__("com.myname.myextension", version="0.0.0")
|
||||
|
||||
def identify(self):
|
||||
"""
|
||||
Demonstrate access to Microscope.camera, and Microscope.stage
|
||||
"""
|
||||
microscope = find_component("org.openflexure.microscope")
|
||||
|
||||
response = (
|
||||
f"My name is {microscope.name}. "
|
||||
f"My parent camera is {microscope.camera}, "
|
||||
f"and my parent stage is {microscope.stage}."
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
def rename(self, new_name):
|
||||
"""
|
||||
Rename the microscope
|
||||
"""
|
||||
|
||||
microscope = find_component("org.openflexure.microscope")
|
||||
|
||||
microscope.name = new_name
|
||||
microscope.save_settings()
|
||||
|
||||
|
||||
# Create your extension object
|
||||
my_extension = MyExtension()
|
||||
53
docs/source/extensions/lifecycle_hooks.rst
Normal file
53
docs/source/extensions/lifecycle_hooks.rst
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
Lifecycle Hooks
|
||||
===============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
In some cases it is useful to have functions triggered by events in an extensions lifecycle. Currently two such lifecycle events can be used, ``on_register``, and ``on_component``.
|
||||
|
||||
``on_register``
|
||||
---------------
|
||||
|
||||
The ``on_register`` method can be used to have a function call as soon as the extension has been successfully registered to the microscope. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class MyExtension(BaseExtension):
|
||||
def __init__(self):
|
||||
|
||||
# Track if the extension has been registered
|
||||
self.registered = False
|
||||
|
||||
# Add lifecycle hooks
|
||||
self.on_register(self.on_register_handler, args=(), kwargs={})
|
||||
|
||||
# Superclass init function
|
||||
super().__init__("com.myname.myextension", version="0.0.0")
|
||||
|
||||
def on_register_handler(self, *args, **kwargs):
|
||||
self.registered = True
|
||||
print("Extension has been registered!")
|
||||
|
||||
|
||||
``on_component``
|
||||
----------------
|
||||
|
||||
The ``on_component`` method can be used to have a function call as soon as a particular LabThings component has been added. This can be used, for example, to get information about the microscope instance as soon as it is available. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class MyExtension(BaseExtension):
|
||||
def __init__(self):
|
||||
|
||||
# Hold a reference to the microscope object as soon as it is available
|
||||
self.microscope = None
|
||||
|
||||
# Add lifecycle hooks
|
||||
self.on_component("com.myname.myextension", self.on_microscope_handler)
|
||||
|
||||
# Superclass init function
|
||||
super().__init__("org.openflexure.microscope", version="0.0.0")
|
||||
|
||||
def on_microscope_handler(self, microscope_object):
|
||||
print("Microscope object has been found!")
|
||||
self.microscope = microscope_object
|
||||
|
|
@ -4,7 +4,7 @@ Basic extension structure
|
|||
An extension starts as a simple instance of :py:class:`labthings.server.extensions.BaseExtension`.
|
||||
Each extension is described by a single ``BaseExtension`` instance, containing any number of methods, API views, and additional hardware components.
|
||||
|
||||
In order to access the currently running microscope object, use the :py:func:`labthings.server.find` function, with the argument ``"org.openflexure.microscope"``. Likewise, any new components attached by other extensions can be found using their full name, as above.
|
||||
In order to access the currently running microscope object, use the :py:func:`labthings.server.find.find_component` function, with the argument ``"org.openflexure.microscope"``. Likewise, any new components attached by other extensions can be found using their full name, as above.
|
||||
|
||||
A simple extension file, with no API views but application-available methods may look like:
|
||||
|
||||
|
|
@ -23,4 +23,14 @@ Once this extension is loaded, any other extensions will have access to your met
|
|||
|
||||
# Call a function from your extension
|
||||
if my_found_extension:
|
||||
my_found_extension.identify()
|
||||
my_found_extension.identify()
|
||||
|
||||
|
||||
Subclassing ``BaseExtension``
|
||||
-------------------------------
|
||||
|
||||
The syntax used above allows novice programmers to easily start building extensions, without having to deal with subclassing. However, for more complex extensions which require persistent state, subclassing :py:class:`labthings.server.extensions.BaseExtension` is recommended.
|
||||
|
||||
The same simple extension as seen above can be written using subclassing:
|
||||
|
||||
.. literalinclude:: ./example_extension/01b_basic_structure_subclass.py
|
||||
|
|
|
|||
|
|
@ -20,15 +20,15 @@ Request arguments
|
|||
|
||||
For POST and PUT requests, data usually needs to be provided to the view in order to perform its function. In this example, our ``rename`` view requires a new microscope name to be passed. We make use of the ``@use_body`` decorator to provide this functionality.
|
||||
|
||||
``@use_body`` defines the type of data expected in the request body. In this example, we ``String`` type data. The arguments of ``fields.String`` allow us to provide additional information, such as the parameter being required, and example values to appear in API documentation.
|
||||
``@use_body`` defines the type of data expected in the request body. In this example, we use ``String`` type data. The arguments of ``fields.String`` allow us to provide additional information, such as the parameter being required, and example values to appear in API documentation.
|
||||
|
||||
Adding additional fields, and the meaning of the field types, will be discussed further in the next section.
|
||||
|
||||
When a POST request is made to our API view, the request body is converted to processed by ``@use_body``, and passed as a positional argument to our ``post`` function.
|
||||
When a POST request is made to our API view, the ``@use_body`` converts the body of the request into a ``String``, and passes it as a positional argument to our ``post`` function.
|
||||
|
||||
Swagger documentation
|
||||
+++++++++++++++++++++
|
||||
|
||||
At this point, it is useful to introduce the automatically generated Swagger documentation. From any web browser, go to ``http://microscope.local/api/v2/swagger-ui`` (or replace ``microscope.local`` with your microscopes IP address on incompatible systems).
|
||||
At this point, it is useful to introduce the automatically generated Swagger documentation. From any web browser, go to ``http://microscope.local/api/v2/swagger-ui`` (or replace ``microscope.local`` with your microscope's IP address if ``microscope.local`` doesn't work for your system).
|
||||
|
||||
This page uses `SwaggerUI <https://swagger.io/tools/swagger-ui/>`_ to provide visual, interactive API documentation. Find your extensions URL in the documentation under the ``extensions`` group. Basic documentation about the parameters required for your POST method should be visible, as well as an interactive example filled out with the example request given in ``@use_body``.
|
||||
This page uses `SwaggerUI <https://swagger.io/tools/swagger-ui/>`_ to provide visual, interactive API documentation. Find your extensions URL in the documentation under the ``extensions`` group. Basic documentation about the parameters required for your POST method should be visible, as well as an interactive example filled out with the example request given in ``@use_body``.
|
||||
|
|
|
|||
|
|
@ -11,4 +11,5 @@ Developing API Extensions
|
|||
./extensions/properties.rst
|
||||
./extensions/actions.rst
|
||||
./extensions/tasks_locks.rst
|
||||
./extensions/ev_gui.rst
|
||||
./extensions/ev_gui.rst
|
||||
./extensions/lifecycle_hooks.rst
|
||||
|
|
@ -21,6 +21,6 @@ For offline (i.e. no real microscope connected) development, a basic development
|
|||
Managing the server
|
||||
-------------------
|
||||
|
||||
Managing the server through the installer script's CLI is documented `on our website <https://openflexure.org/projects/microscope/install/#managing-the-microscope-server>`_.
|
||||
Managing the server through the installer script's CLI is documented `on our website <https://openflexure.org/projects/microscope/install#managing-the-microscope-server>`_.
|
||||
|
||||
This includes starting the server as a background service, as well as starting a development server with real-time debug logging.
|
||||
Loading…
Add table
Add a link
Reference in a new issue