diff --git a/openflexure_microscope/api/v1/views.py b/openflexure_microscope/api/v1/views.py index f223e592..e4d67efc 100644 --- a/openflexure_microscope/api/v1/views.py +++ b/openflexure_microscope/api/v1/views.py @@ -2,25 +2,25 @@ from flask.views import MethodView class MicroscopeView(MethodView): - + """ + Create a generic MethodView with a globally available + microscope object passed as an argument. + """ def __init__(self, microscope, **kwargs): - """ - Create a generic MethodView with a globally available - microscope object passed as an argument. - """ + self.microscope = microscope MethodView.__init__(self, **kwargs) class MicroscopeViewPlugin(MicroscopeView): - + """ + Create a generic MethodView with a globally available + microscope object passed as an argument, and a plugin + reference stored in 'self'. Initially None. + """ def __init__(self, microscope, plugin=None, **kwargs): - """ - Create a generic MethodView with a globally available - microscope object passed as an argument, and a plugin - reference stored in 'self'. Initially None - """ + self.plugin = plugin MicroscopeView.__init__(self, microscope=microscope, **kwargs) \ No newline at end of file diff --git a/openflexure_microscope/plugins/default/api.py b/openflexure_microscope/plugins/default/api.py index ca0ce594..26bdf282 100644 --- a/openflexure_microscope/plugins/default/api.py +++ b/openflexure_microscope/plugins/default/api.py @@ -12,19 +12,9 @@ class IdentifyAPI(MicroscopeViewPlugin): """ def get(self): """ - Method to call when an HTTP GET request is made. + Default plugin to return a plaintext representation of the camera and stage objects. + + .. :quickref: Default plugin; Show representation of camera and stage objects. """ data = self.microscope.plugin.default.identify() # Call a method from our plugin, using the full route - return Response(escape(data)) - - -class HelloWorldAPI(MicroscopeViewPlugin): - """ - An even simpler example API plugin, which just returns static data without using the microscope. - """ - def get(self): - """ - Method to call when an HTTP GET request is made. - """ - data = self.plugin.hello_world() # Call a method from our plugin, using the MicroscopeViewPlugin.plugin shortcut - return Response(data) + return Response(escape(data)) \ No newline at end of file diff --git a/openflexure_microscope/plugins/default/plugin.py b/openflexure_microscope/plugins/default/plugin.py index 39261c6e..eb66cee3 100644 --- a/openflexure_microscope/plugins/default/plugin.py +++ b/openflexure_microscope/plugins/default/plugin.py @@ -1,6 +1,6 @@ from openflexure_microscope.plugins import MicroscopePlugin -from .api import IdentifyAPI, HelloWorldAPI +from .api import IdentifyAPI class Plugin(MicroscopePlugin): @@ -10,7 +10,6 @@ class Plugin(MicroscopePlugin): api_views = { '/identify': IdentifyAPI, - '/hello': HelloWorldAPI, } def identify(self): @@ -21,10 +20,3 @@ class Plugin(MicroscopePlugin): response = "My parent camera is {}, and my parent stage is {}.".format(self.microscope.camera, self.microscope.stage) print(response) return response - - def hello_world(self): - """ - Demonstrate passive method - """ - - return "Hello world!" \ No newline at end of file diff --git a/openflexure_microscope/plugins/example/__init__.py b/openflexure_microscope/plugins/example/__init__.py new file mode 100644 index 00000000..b1d5b636 --- /dev/null +++ b/openflexure_microscope/plugins/example/__init__.py @@ -0,0 +1,4 @@ +__all__ = ['Plugin', 'HelloWorldAPI', 'IdentifyAPI'] + +from .plugin import Plugin +from .api import HelloWorldAPI, IdentifyAPI \ No newline at end of file diff --git a/openflexure_microscope/plugins/example/api.py b/openflexure_microscope/plugins/example/api.py new file mode 100644 index 00000000..7b023132 --- /dev/null +++ b/openflexure_microscope/plugins/example/api.py @@ -0,0 +1,53 @@ +from openflexure_microscope.api.utilities import parse_payload, get_from_payload +from openflexure_microscope.api.v1.views import MicroscopeViewPlugin + +from flask import request, Response, escape + +import logging + + +class IdentifyAPI(MicroscopeViewPlugin): + """ + A simple example API plugin, attached through the main microscope plugin. + """ + def get(self): + """ + Method to call when an HTTP GET request is made. + """ + data = self.plugin.identify() # Call a method from our plugin, using the MicroscopeViewPlugin.plugin shortcut + return Response(escape(data)) + + +class HelloWorldAPI(MicroscopeViewPlugin): + """ + A method to create, set, and return a new microscope parameter. + """ + + def get(self): + """ + Method to call when an HTTP GET request is made. + """ + + # If the microscope does not already contain our plugin_string attribute + if not hasattr(self.microscope, 'plugin_string'): + # Make a string, using the MicroscopeViewPlugin.plugin shortcut + self.microscope.plugin_string = self.plugin.hello_world() + + return Response(self.microscope.plugin_string) + + def post(self): + """ + Method to call when an HTTP POST request is made. + Assumes request will include a JSON payload. + """ + # Get payload JSON as a dictionary + state = parse_payload(request) + + # Extract a value from the JSON key 'plugin_string'. If no value is given, default to None + new_plugin_string = get_from_payload(state, 'plugin_string', default=None) + + if new_plugin_string: # If not None or empty + # Set microscope attribute to the specified string + self.microscope.plugin_string = new_plugin_string + + return Response(self.microscope.plugin_string) diff --git a/openflexure_microscope/plugins/example/plugin.py b/openflexure_microscope/plugins/example/plugin.py new file mode 100644 index 00000000..39261c6e --- /dev/null +++ b/openflexure_microscope/plugins/example/plugin.py @@ -0,0 +1,30 @@ +from openflexure_microscope.plugins import MicroscopePlugin + +from .api import IdentifyAPI, HelloWorldAPI + + +class Plugin(MicroscopePlugin): + """ + A set of default plugins + """ + + api_views = { + '/identify': IdentifyAPI, + '/hello': HelloWorldAPI, + } + + def identify(self): + """ + Demonstrate access to Microscope.camera, and Microscope.stage + """ + + response = "My parent camera is {}, and my parent stage is {}.".format(self.microscope.camera, self.microscope.stage) + print(response) + return response + + def hello_world(self): + """ + Demonstrate passive method + """ + + return "Hello world!" \ No newline at end of file diff --git a/openflexure_microscope/plugins/loader.py b/openflexure_microscope/plugins/loader.py index 566c563d..7a56dd29 100644 --- a/openflexure_microscope/plugins/loader.py +++ b/openflexure_microscope/plugins/loader.py @@ -40,7 +40,7 @@ def load_plugin_module(plugin_path): # First, try importing from standard modules try: plugin_module = importlib.import_module(plugin_path) - except ModuleNotFoundError: + except ImportError: plugin_spec, plugin_module, plugin_name = module_from_file(plugin_path) # If a valid plugin was found