Merge branch 'master' into 'rwb27-plugin-comments'

# Conflicts:
#   docs/source/extensions/structure.rst
This commit is contained in:
Joel Collins 2020-03-24 11:17:11 +00:00
commit 7c59245753
65 changed files with 1829 additions and 844 deletions

View file

@ -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()

View file

@ -14,7 +14,7 @@ from labthings.server import fields
class MicroscopeIdentifySchema(Schema):
name = fields.String() # Microscopes name
id = fields.UUID() # Microscopes unique ID
status = fields.Dict() # Status dictionary
state = fields.Dict() # Status dictionary
camera = fields.String() # Camera object (represented as a string)
stage = fields.String() # Stage object (represented as a string)

View file

@ -19,7 +19,7 @@ from labthings.server import fields
class MicroscopeIdentifySchema(Schema):
name = fields.String() # Microscopes name
id = fields.UUID() # Microscopes unique ID
status = fields.Dict() # Status dictionary
state = fields.Dict() # Status dictionary
camera = fields.String() # Camera object (represented as a string)
stage = fields.String() # Stage object (represented as a string)

View file

@ -24,7 +24,7 @@ import io # Used in our capture action
class MicroscopeIdentifySchema(Schema):
name = fields.String() # Microscopes name
id = fields.UUID() # Microscopes unique ID
status = fields.Dict() # Status dictionary
state = fields.Dict() # Status dictionary
camera = fields.String() # Camera object (represented as a string)
stage = fields.String() # Stage object (represented as a string)

View 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

View file

@ -107,7 +107,7 @@ We start by creating a schema to describe how to serialise a :py:class:`openflex
class MicroscopeIdentifySchema(Schema):
name = fields.String() # Microscopes name
id = fields.UUID() # Microscopes unique ID
status = fields.Dict() # Status dictionary
state = fields.Dict() # Status dictionary
camera = fields.String() # Camera object (represented as a string)
stage = fields.String() # Stage object (represented as a string)

View file

@ -24,3 +24,13 @@ 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()
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