openflexure-microscope-server/openflexure_microscope/api/utilities/gui.py
2020-11-30 13:36:45 +00:00

62 lines
2.2 KiB
Python

import copy
import logging
from functools import wraps
from typing import Callable, Union
from labthings.extensions import BaseExtension
def clean_rule(rule: str):
while rule[0] == "/":
rule = rule[1:]
return f"{rule}"
def build_gui_from_dict(gui_description: dict, extension_object: BaseExtension):
# Make a working copy of GUI description
api_gui = copy.deepcopy(gui_description)
# Grab the extensions rules dictionary
# TODO: Public property should be added to LabThings
ext_rules = extension_object._rules # pylint: disable=protected-access
# Expand shorthand routes into full relative URLs
if "forms" in gui_description and isinstance(api_gui["forms"], list):
for form in api_gui["forms"]:
# Clean leading slashes from rule
if "route" in form:
form["route"] = clean_rule(form["route"])
# Match rule in extension object
if "route" in form and form["route"] in ext_rules.keys():
form["route"] = ext_rules[form["route"]]["urls"][0]
else:
logging.warning("No valid expandable route found for %s", form["route"])
# Inject extension information
api_gui["id"] = extension_object.name
api_gui["version"] = extension_object.version
return api_gui
def build_gui_from_func(func: Callable, extension_object: BaseExtension):
@wraps(func)
def wrapped(*args, **kwargs):
return build_gui_from_dict(func(*args, **kwargs), extension_object)
return wrapped
def build_gui(gui_description: Union[dict, Callable], extension_object: BaseExtension):
# If given a function that generates a GUI dictionary
if callable(gui_description):
# Wrap in the route expander
return build_gui_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 build_gui_from_func(gui_description_func, extension_object)
else:
raise RuntimeError("GUI description must be a function or a dictionary")