Moved eV GUI stuff out of LabThings

This commit is contained in:
Joel Collins 2020-01-07 22:25:19 +00:00
parent 3fef94dc95
commit eeb15453d0
5 changed files with 169 additions and 33 deletions

View file

@ -0,0 +1,113 @@
from openflexure_microscope.common.flask_labthings.resource import Resource
from openflexure_microscope.common.flask_labthings.extensions import BaseExtension
from openflexure_microscope.api.utilities.gui import expand_routes
import logging
from flask import jsonify
# Some value that will change over time
# Here, we add 1 to it every time a GET request is made
val_int = 0
def dynamic_form():
return {
"id": "test-plugin",
"icon": "pets",
"forms": [
{
"name": "Simple request",
"isCollapsible": False,
"isTask": False,
"selfUpdate": True,
"route": "/do",
"submitLabel": "Do things",
"schema": [
{
"fieldType": "numberInput",
"name": "val_int",
"label": "Number value",
"minValue": 0,
},
{
"fieldType": "htmlBlock",
"name": "html_block",
"content": f"<i>Value is: </i><br>{val_int}.", # We dynamically use the val_int variable
},
],
}
],
}
# Alternate form without any dynamic parts
static_form = {
"id": "test-plugin",
"icon": "pets",
"forms": [
{
"name": "Simple request",
"isCollapsible": False,
"isTask": False,
"selfUpdate": True,
"route": "/do",
"submitLabel": "Do things",
"schema": [
{
"fieldType": "numberInput",
"name": "val_int",
"label": "Number value",
"minValue": 0,
},
{
"fieldType": "htmlBlock",
"name": "html_block",
"content": f"<i>Value is fixed</i>.",
},
],
}
],
}
class TestAPIView(Resource):
def get(self):
global val_int
val_int += 1
return jsonify({"val": True})
class TestDoAPIView(Resource):
def post(self):
global val_int
val_int += 1
return jsonify({"val": True})
# Using the dynamic form
dynamic_test_extension_v2 = BaseExtension("dynamic_test_extension")
dynamic_test_extension_v2.add_view(
TestAPIView, "/get", endpoint="dynamic_test_extension_get"
)
dynamic_test_extension_v2.add_view(
TestDoAPIView, "/do", endpoint="dynamic_test_extension_do"
)
dynamic_test_extension_v2.add_meta(
"gui", expand_routes(dynamic_form, dynamic_test_extension_v2)
)
# Using the static form
static_test_extension_v2 = BaseExtension("static_test_extension")
static_test_extension_v2.add_view(
TestAPIView, "/get", endpoint="static_test_extension_get"
)
static_test_extension_v2.add_view(
TestDoAPIView, "/do", endpoint="static_test_extension_do"
)
static_test_extension_v2.add_meta(
"gui", expand_routes(static_form, static_test_extension_v2)
)

View file

@ -4,6 +4,8 @@ import errno
from werkzeug.exceptions import BadRequest
from flask import url_for, Blueprint, current_app
from . import gui
def view_class_from_endpoint(endpoint: str):
return current_app.view_functions[endpoint].view_class

View file

@ -0,0 +1,41 @@
import copy
import logging
from functools import wraps
def expand_routes_from_dict(gui_description, extension_object):
api_gui = copy.deepcopy(gui_description)
if "forms" in gui_description and isinstance(api_gui["forms"], list):
for form in api_gui["forms"]:
if "route" in form and form["route"] in extension_object._rules.keys():
form["route"] = extension_object._rules[form["route"]]["rule"]
else:
logging.warn(
"No valid expandable route found for {}".format(form["route"])
)
return api_gui
def expand_routes_from_func(func, extension_object):
@wraps(func)
def wrapped(*args, **kwargs):
return expand_routes_from_dict(func(*args, **kwargs), extension_object)
return wrapped
def expand_routes(gui_description, extension_object):
# If given a function that generates a GUI dictionary
if callable(gui_description):
# Wrap in the route expander
return expand_routes_from_func(gui_description, extension_object)
# If given a dictionary directly
elif isinstance(gui_description, dict):
# Build a GUI generator function
def gui_description_func():
return gui_description
# Wrap in the route expander
return expand_routes_from_func(gui_description_func, extension_object)
else:
raise RuntimeError("GUI description must be a function or a dictionary")