Renamed LabThing plugins to extensions
This commit is contained in:
parent
d96e188d16
commit
2a245185a6
10 changed files with 89 additions and 89 deletions
|
|
@ -11,16 +11,16 @@ from datetime import datetime
|
|||
|
||||
from flask_cors import CORS
|
||||
|
||||
from openflexure_microscope.api.utilities import list_routes, init_default_plugins
|
||||
from openflexure_microscope.api.utilities import list_routes, init_default_extensions
|
||||
|
||||
from openflexure_microscope.config import (
|
||||
settings_file_path,
|
||||
JSONEncoder,
|
||||
USER_PLUGINS_PATH,
|
||||
USER_EXTENSIONS_PATH,
|
||||
)
|
||||
|
||||
from openflexure_microscope.common.flask_labthings.labthing import LabThing
|
||||
from openflexure_microscope.common.flask_labthings.plugins import find_plugins
|
||||
from openflexure_microscope.common.flask_labthings.extensions import find_extensions
|
||||
|
||||
from openflexure_microscope.api.microscope import default_microscope as api_microscope
|
||||
|
||||
|
|
@ -73,11 +73,11 @@ labthing.title = f"OpenFlexure Microscope {api_microscope.name}"
|
|||
# Attach lab devices
|
||||
labthing.register_device(api_microscope, "openflexure_microscope")
|
||||
|
||||
# Attach plugins
|
||||
if not os.path.isfile(USER_PLUGINS_PATH):
|
||||
init_default_plugins(USER_PLUGINS_PATH)
|
||||
for plugin in find_plugins(USER_PLUGINS_PATH):
|
||||
labthing.register_plugin(plugin)
|
||||
# Attach extensions
|
||||
if not os.path.isfile(USER_EXTENSIONS_PATH):
|
||||
init_default_extensions(USER_EXTENSIONS_PATH)
|
||||
for extension in find_extensions(USER_EXTENSIONS_PATH):
|
||||
labthing.register_extension(extension)
|
||||
|
||||
# Attach captures resources
|
||||
labthing.add_resource(views.CaptureList, f"/captures")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from openflexure_microscope.common.flask_labthings.find import find_device
|
||||
from openflexure_microscope.common.flask_labthings.plugins import BasePlugin
|
||||
from openflexure_microscope.common.flask_labthings.extensions import BaseExtension
|
||||
from openflexure_microscope.common.flask_labthings.resource import Resource
|
||||
|
||||
from openflexure_microscope.devel import JsonResponse, request, jsonify, taskify, abort
|
||||
|
|
@ -139,7 +139,7 @@ def sharpness_edge(image):
|
|||
)
|
||||
|
||||
|
||||
### Autofocus plugin
|
||||
### Autofocus extension
|
||||
|
||||
|
||||
def measure_sharpness(microscope, metric_fn=sharpness_sum_lap2):
|
||||
|
|
@ -353,15 +353,15 @@ class FastAutofocusAPI(Resource):
|
|||
abort(503, "No stage connected. Unable to autofocus.")
|
||||
|
||||
|
||||
autofocus_plugin_v2 = BasePlugin("autofocus")
|
||||
autofocus_extension_v2 = BaseExtension("autofocus")
|
||||
|
||||
autofocus_plugin_v2.add_method(fast_autofocus, "fast_autofocus")
|
||||
autofocus_plugin_v2.add_method(autofocus, "autofocus")
|
||||
autofocus_extension_v2.add_method(fast_autofocus, "fast_autofocus")
|
||||
autofocus_extension_v2.add_method(autofocus, "autofocus")
|
||||
|
||||
autofocus_plugin_v2.add_view(MeasureSharpnessAPI, "/measure_sharpness")
|
||||
autofocus_extension_v2.add_view(MeasureSharpnessAPI, "/measure_sharpness")
|
||||
|
||||
autofocus_plugin_v2.add_view(AutofocusAPI, "/autofocus")
|
||||
autofocus_plugin_v2.register_action(AutofocusAPI)
|
||||
autofocus_extension_v2.add_view(AutofocusAPI, "/autofocus")
|
||||
autofocus_extension_v2.register_action(AutofocusAPI)
|
||||
|
||||
autofocus_plugin_v2.add_view(FastAutofocusAPI, "/fast_autofocus")
|
||||
autofocus_plugin_v2.register_action(FastAutofocusAPI)
|
||||
autofocus_extension_v2.add_view(FastAutofocusAPI, "/fast_autofocus")
|
||||
autofocus_extension_v2.register_action(FastAutofocusAPI)
|
||||
|
|
@ -6,8 +6,8 @@ from typing import Tuple
|
|||
from functools import reduce
|
||||
|
||||
from openflexure_microscope.camera.base import generate_basename
|
||||
from openflexure_microscope.common.flask_labthings.find import find_device, find_plugin
|
||||
from openflexure_microscope.common.flask_labthings.plugins import BasePlugin
|
||||
from openflexure_microscope.common.flask_labthings.find import find_device, find_extension
|
||||
from openflexure_microscope.common.flask_labthings.extensions import BaseExtension
|
||||
|
||||
from openflexure_microscope.devel import (
|
||||
JsonResponse,
|
||||
|
|
@ -169,10 +169,10 @@ def tile(
|
|||
)
|
||||
|
||||
# Check if autofocus is enabled
|
||||
autofocus_plugin = find_plugin("autofocus")
|
||||
autofocus_extension = find_extension("autofocus")
|
||||
if (
|
||||
autofocus_dz
|
||||
and autofocus_plugin
|
||||
and autofocus_extension
|
||||
and microscope.has_real_stage()
|
||||
and microscope.has_real_camera()
|
||||
):
|
||||
|
|
@ -211,7 +211,7 @@ def tile(
|
|||
# Refocus
|
||||
if autofocus_enabled:
|
||||
if fast_autofocus:
|
||||
autofocus_plugin.fast_autofocus(
|
||||
autofocus_extension.fast_autofocus(
|
||||
dz=autofocus_dz,
|
||||
target_z=-z_stack_dz / 2.0, # Finish below the focus
|
||||
initial_move_up=False, # We're already at the top of the scan
|
||||
|
|
@ -219,7 +219,7 @@ def tile(
|
|||
# TODO: save the focus data for future reference? Use it for diagnostics?
|
||||
else:
|
||||
logging.debug("Running autofocus")
|
||||
autofocus_plugin.autofocus(
|
||||
autofocus_extension.autofocus(
|
||||
range(-3 * autofocus_dz, 4 * autofocus_dz, autofocus_dz)
|
||||
)
|
||||
logging.debug("Finished autofocus")
|
||||
|
|
@ -398,7 +398,7 @@ class TileScanAPI(Resource):
|
|||
return jsonify(task.state), 201
|
||||
|
||||
|
||||
scan_plugin_v2 = BasePlugin("scan")
|
||||
scan_extension_v2 = BaseExtension("scan")
|
||||
|
||||
scan_plugin_v2.add_view(TileScanAPI, "/tile")
|
||||
scan_plugin_v2.register_action(TileScanAPI)
|
||||
scan_extension_v2.add_view(TileScanAPI, "/tile")
|
||||
scan_extension_v2.register_action(TileScanAPI)
|
||||
|
|
@ -108,22 +108,22 @@ def create_file(config_path):
|
|||
raise
|
||||
|
||||
|
||||
def init_default_plugins(plugin_path):
|
||||
global _DEFAULT_PLUGIN_INIT
|
||||
os.makedirs(os.path.dirname(plugin_path), exist_ok=True)
|
||||
def init_default_extensions(extension_path):
|
||||
global _DEFAULT_extension_INIT
|
||||
os.makedirs(os.path.dirname(extension_path), exist_ok=True)
|
||||
|
||||
if not os.path.exists(plugin_path): # If user plugins file doesn't exist
|
||||
logging.warning("No plugin file found at {}. Creating...".format(plugin_path))
|
||||
create_file(plugin_path)
|
||||
if not os.path.exists(extension_path): # If user extensions file doesn't exist
|
||||
logging.warning("No extension file found at {}. Creating...".format(extension_path))
|
||||
create_file(extension_path)
|
||||
|
||||
logging.info("Populating {}...".format(plugin_path))
|
||||
with open(plugin_path, "w") as outfile:
|
||||
outfile.write(_DEFAULT_PLUGIN_INIT)
|
||||
logging.info("Populating {}...".format(extension_path))
|
||||
with open(extension_path, "w") as outfile:
|
||||
outfile.write(_DEFAULT_extension_INIT)
|
||||
|
||||
|
||||
_DEFAULT_PLUGIN_INIT = """
|
||||
from openflexure_microscope.api.default_plugins.autofocus import autofocus_plugin_v2
|
||||
from openflexure_microscope.api.default_plugins.scan import scan_plugin_v2
|
||||
_DEFAULT_extension_INIT = """
|
||||
from openflexure_microscope.api.default_extensions.autofocus import autofocus_extension_v2
|
||||
from openflexure_microscope.api.default_extensions.scan import scan_extension_v2
|
||||
|
||||
__plugins__ = [autofocus_plugin_v2, scan_plugin_v2]
|
||||
__extensions__ = [autofocus_extension_v2, scan_extension_v2]
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ from openflexure_microscope.common.labthings_core.utilities import get_docstring
|
|||
from openflexure_microscope.utilities import camel_to_snake, snake_to_spine
|
||||
|
||||
|
||||
class BasePlugin:
|
||||
class BaseExtension:
|
||||
"""
|
||||
Parent class for all plugins.
|
||||
Parent class for all extensions.
|
||||
|
||||
Handles binding route views and forms.
|
||||
"""
|
||||
|
|
@ -23,7 +23,7 @@ class BasePlugin:
|
|||
self._rules = {} # Key: Original rule. Val: View class
|
||||
self._gui = None
|
||||
|
||||
self._cls = str(self) # String description of plugin instance
|
||||
self._cls = str(self) # String description of extension instance
|
||||
|
||||
self.actions = []
|
||||
self.properties = []
|
||||
|
|
@ -43,7 +43,7 @@ class BasePlugin:
|
|||
while cleaned_rule[0] == "/":
|
||||
cleaned_rule = cleaned_rule[1:]
|
||||
|
||||
# Expand the rule to include plugin name
|
||||
# Expand the rule to include extension name
|
||||
full_rule = "/{}/{}".format(self._name_uri_safe, cleaned_rule)
|
||||
|
||||
view_id = cleaned_rule.replace("/", "_").replace("<", "").replace(">", "")
|
||||
|
|
@ -119,20 +119,20 @@ class BasePlugin:
|
|||
setattr(self, method_name, method)
|
||||
else:
|
||||
logging.warning(
|
||||
"Unable to bind method to plugin. Method name already exists."
|
||||
"Unable to bind method to extension. Method name already exists."
|
||||
)
|
||||
|
||||
|
||||
def find_plugins(plugin_path, module_name="plugins"):
|
||||
logging.debug(f"Loading plugins from {plugin_path}")
|
||||
def find_extensions(extension_path, module_name="extensions"):
|
||||
logging.debug(f"Loading extensions from {extension_path}")
|
||||
|
||||
spec = util.spec_from_file_location(module_name, plugin_path)
|
||||
spec = util.spec_from_file_location(module_name, extension_path)
|
||||
mod = util.module_from_spec(spec)
|
||||
sys.modules[spec.name] = mod
|
||||
|
||||
spec.loader.exec_module(mod)
|
||||
|
||||
if hasattr(mod, "__plugins__"):
|
||||
return mod.__plugins__
|
||||
if hasattr(mod, "__extensions__"):
|
||||
return mod.__extensions__
|
||||
else:
|
||||
return None
|
||||
|
|
@ -15,10 +15,10 @@ def current_labthing():
|
|||
return app.extensions[EXTENSION_NAME]
|
||||
|
||||
|
||||
def registered_plugins(labthing_instance=None):
|
||||
def registered_extensions(labthing_instance=None):
|
||||
if not labthing_instance:
|
||||
labthing_instance = current_labthing()
|
||||
return labthing_instance.plugins
|
||||
return labthing_instance.extensions
|
||||
|
||||
|
||||
def registered_devices(labthing_instance=None):
|
||||
|
|
@ -37,14 +37,14 @@ def find_device(device_name, labthing_instance=None):
|
|||
return None
|
||||
|
||||
|
||||
def find_plugin(plugin_name, labthing_instance=None):
|
||||
def find_extension(extension_name, labthing_instance=None):
|
||||
if not labthing_instance:
|
||||
labthing_instance = current_labthing()
|
||||
|
||||
logging.debug("Current labthing:")
|
||||
logging.debug(current_labthing())
|
||||
|
||||
if plugin_name in labthing_instance.plugins:
|
||||
return labthing_instance.plugins[plugin_name]
|
||||
if extension_name in labthing_instance.extensions:
|
||||
return labthing_instance.extensions[extension_name]
|
||||
else:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ from flask import url_for, jsonify
|
|||
from apispec import APISpec
|
||||
from apispec.ext.marshmallow import MarshmallowPlugin
|
||||
|
||||
from .plugins import BasePlugin
|
||||
from .views.plugins import PluginListResource
|
||||
from .extensions import BaseExtension
|
||||
from .views.extensions import ExtensionListResource
|
||||
from .views.tasks import TaskList, TaskResource
|
||||
|
||||
from .spec import view2path
|
||||
|
|
@ -32,7 +32,7 @@ class LabThing(object):
|
|||
|
||||
self.devices = {}
|
||||
|
||||
self.plugins = {}
|
||||
self.extensions = {}
|
||||
|
||||
self.resources = []
|
||||
self.properties = {}
|
||||
|
|
@ -121,9 +121,9 @@ class LabThing(object):
|
|||
self._complete_url("/swagger", ""), "swagger", self.swagger
|
||||
)
|
||||
|
||||
# Add plugin overview
|
||||
self.add_resource(PluginListResource, "/plugins")
|
||||
self.register_property(PluginListResource)
|
||||
# Add extension overview
|
||||
self.add_resource(ExtensionListResource, "/extensions")
|
||||
self.register_property(ExtensionListResource)
|
||||
# Add task routes
|
||||
self.add_resource(TaskList, "/tasks")
|
||||
self.register_property(TaskList)
|
||||
|
|
@ -134,26 +134,26 @@ class LabThing(object):
|
|||
def register_device(self, device_object, device_name: str):
|
||||
self.devices[device_name] = device_object
|
||||
|
||||
### Plugin stuff
|
||||
### Extension stuff
|
||||
|
||||
def register_plugin(self, plugin_object):
|
||||
if isinstance(plugin_object, BasePlugin):
|
||||
self.plugins[plugin_object.name] = plugin_object
|
||||
def register_extension(self, extension_object):
|
||||
if isinstance(extension_object, BaseExtension):
|
||||
self.extensions[extension_object.name] = extension_object
|
||||
else:
|
||||
raise TypeError("Plugin object must be an instance of BasePlugin")
|
||||
raise TypeError("Extension object must be an instance of BaseExtension")
|
||||
|
||||
for plugin_view_id, plugin_view in plugin_object.views.items():
|
||||
# Add route to the plugins blueprint
|
||||
for extension_view_id, extension_view in extension_object.views.items():
|
||||
# Add route to the extensions blueprint
|
||||
self.add_resource(
|
||||
plugin_view["view"],
|
||||
"/plugins" + plugin_view["rule"],
|
||||
**plugin_view["kwargs"],
|
||||
extension_view["view"],
|
||||
"/extensions" + extension_view["rule"],
|
||||
**extension_view["kwargs"],
|
||||
)
|
||||
|
||||
for prop in plugin_object.properties:
|
||||
for prop in extension_object.properties:
|
||||
self.register_property(prop)
|
||||
|
||||
for action in plugin_object.actions:
|
||||
for action in extension_object.actions:
|
||||
self.register_action(action)
|
||||
|
||||
### Resource stuff
|
||||
|
|
@ -327,9 +327,9 @@ class LabThing(object):
|
|||
"description": get_docstring(self.swagger),
|
||||
"methods": ["GET"],
|
||||
},
|
||||
"plugins": {
|
||||
"href": self.url_for(PluginListResource, _external=True),
|
||||
**description_from_view(PluginListResource),
|
||||
"extensions": {
|
||||
"href": self.url_for(ExtensionListResource, _external=True),
|
||||
**description_from_view(ExtensionListResource),
|
||||
},
|
||||
"tasks": {
|
||||
"href": self.url_for(TaskList, _external=True),
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
"""
|
||||
Top-level representation of attached and enabled plugins
|
||||
Top-level representation of attached and enabled Extensions
|
||||
"""
|
||||
|
||||
from openflexure_microscope.common.labthings_core.utilities import get_docstring
|
||||
from ..utilities import description_from_view
|
||||
|
||||
from openflexure_microscope.common.flask_labthings.resource import Resource
|
||||
from openflexure_microscope.common.flask_labthings.find import registered_plugins
|
||||
from openflexure_microscope.common.flask_labthings.find import registered_extensions
|
||||
from openflexure_microscope.common.flask_labthings.schema import Schema
|
||||
from openflexure_microscope.common.flask_labthings.decorators import marshal_with
|
||||
from openflexure_microscope.common.flask_labthings import fields
|
||||
|
|
@ -17,7 +17,7 @@ from flask import jsonify, url_for
|
|||
import logging
|
||||
|
||||
|
||||
class PluginSchema(Schema):
|
||||
class ExtensionSchema(Schema):
|
||||
name = fields.String(data_key="title")
|
||||
_name_python_safe = fields.String(data_key="pythonName")
|
||||
_cls = fields.String(data_key="pythonObject")
|
||||
|
|
@ -44,23 +44,23 @@ class PluginSchema(Schema):
|
|||
return data
|
||||
|
||||
|
||||
class PluginListResource(Resource):
|
||||
class ExtensionListResource(Resource):
|
||||
"""
|
||||
List and basic documentation for all enabled plugins
|
||||
List and basic documentation for all enabled Extensions
|
||||
"""
|
||||
|
||||
@marshal_with(PluginSchema(many=True))
|
||||
@marshal_with(ExtensionSchema(many=True))
|
||||
def get(self):
|
||||
"""
|
||||
Return the current plugin forms
|
||||
Return the current Extension forms
|
||||
|
||||
.. :quickref: Plugin; Get forms
|
||||
.. :quickref: Extension; Get forms
|
||||
|
||||
Returns an array of present plugin forms (describing plugin user interfaces.)
|
||||
Please note, this is *not* a list of all enabled plugins, only those with associated
|
||||
Returns an array of present Extension forms (describing Extension user interfaces.)
|
||||
Please note, this is *not* a list of all enabled Extensions, only those with associated
|
||||
user interface forms.
|
||||
|
||||
A complete list of enabled plugins can be found in the microscope state.
|
||||
A complete list of enabled Extensions can be found in the microscope state.
|
||||
|
||||
"""
|
||||
return registered_plugins().values()
|
||||
return registered_extensions().values()
|
||||
|
|
@ -182,7 +182,7 @@ DEFAULT_CONFIG_FILE_PATH = os.path.join(HERE, "microscope_settings.default.json"
|
|||
|
||||
USER_CONFIG_DIR = os.path.join(os.path.expanduser("~"), ".openflexure")
|
||||
USER_CONFIG_FILE_PATH = os.path.join(USER_CONFIG_DIR, "microscope_settings.json")
|
||||
USER_PLUGINS_PATH = os.path.join(USER_CONFIG_DIR, "microscope_plugins", "__init__.py")
|
||||
USER_EXTENSIONS_PATH = os.path.join(USER_CONFIG_DIR, "microscope_extensions", "__init__.py")
|
||||
|
||||
# Load the default config
|
||||
with open(DEFAULT_CONFIG_FILE_PATH, "r") as default_rc:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue