From 585633020b12a291549f9dc46c0c6f1d5483de36 Mon Sep 17 00:00:00 2001 From: jtc42 Date: Sun, 5 Jan 2020 20:02:22 +0000 Subject: [PATCH] Automatically register all extensions in the extension directory (without explicit init import) --- .../api/default_extensions/__init__.py | 3 ++ openflexure_microscope/api/utilities.py | 12 ++------ .../common/flask_labthings/extensions.py | 29 +++++++++++++++++-- openflexure_microscope/config.py | 2 +- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/openflexure_microscope/api/default_extensions/__init__.py b/openflexure_microscope/api/default_extensions/__init__.py index e69de29b..3508bead 100644 --- a/openflexure_microscope/api/default_extensions/__init__.py +++ b/openflexure_microscope/api/default_extensions/__init__.py @@ -0,0 +1,3 @@ +from .autofocus import autofocus_extension_v2 +from .scan import scan_extension_v2 +from .zip_builder import zip_extension_v2 \ No newline at end of file diff --git a/openflexure_microscope/api/utilities.py b/openflexure_microscope/api/utilities.py index 393bd736..ada63330 100644 --- a/openflexure_microscope/api/utilities.py +++ b/openflexure_microscope/api/utilities.py @@ -109,7 +109,7 @@ def create_file(config_path): def init_default_extensions(extension_path): - global _DEFAULT_extension_INIT + global _DEFAULT_EXTENSION_INIT os.makedirs(os.path.dirname(extension_path), exist_ok=True) if not os.path.exists(extension_path): # If user extensions file doesn't exist @@ -118,13 +118,7 @@ def init_default_extensions(extension_path): logging.info("Populating {}...".format(extension_path)) with open(extension_path, "w") as outfile: - outfile.write(_DEFAULT_extension_INIT) + outfile.write(_DEFAULT_EXTENSION_INIT) -_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 -from openflexure_microscope.api.default_extensions.zip_builder import zip_extension_v2 - -__extensions__ = [autofocus_extension_v2, scan_extension_v2, zip_extension_v2] -""" +_DEFAULT_EXTENSION_INIT = "from openflexure_microscope.api.default_extensions import *" diff --git a/openflexure_microscope/common/flask_labthings/extensions.py b/openflexure_microscope/common/flask_labthings/extensions.py index d433b235..5571bd83 100644 --- a/openflexure_microscope/common/flask_labthings/extensions.py +++ b/openflexure_microscope/common/flask_labthings/extensions.py @@ -4,6 +4,8 @@ import copy from importlib import util import sys +import os +import glob from openflexure_microscope.common.labthings_core.utilities import get_docstring from openflexure_microscope.utilities import camel_to_snake, snake_to_spine @@ -123,7 +125,16 @@ class BaseExtension: ) -def find_extensions(extension_path, module_name="extensions"): +def find_instances_in_module(module, class_to_find): + objs = [] + for attribute in dir(module): + if not attribute.startswith("__"): + if isinstance(getattr(module, attribute), class_to_find): + objs.append(getattr(module, attribute)) + return objs + + +def find_extensions_in_file(extension_path, module_name="extensions"): logging.debug(f"Loading extensions from {extension_path}") spec = util.spec_from_file_location(module_name, extension_path) @@ -133,6 +144,18 @@ def find_extensions(extension_path, module_name="extensions"): spec.loader.exec_module(mod) if hasattr(mod, "__extensions__"): - return mod.__extensions__ + return [getattr(mod, ext_name) for ext_name in mod.__extensions__] else: - return None + return find_instances_in_module(mod, BaseExtension) + + +def find_extensions(extension_dir, module_name="extensions"): + logging.debug(f"Loading extensions from {extension_dir}") + + extensions = [] + extension_paths = glob.glob(os.path.join(extension_dir, "*.py")) + + for extension_path in extension_paths: + extensions.extend(find_extensions_in_file(extension_path, module_name=module_name)) + + return extensions \ No newline at end of file diff --git a/openflexure_microscope/config.py b/openflexure_microscope/config.py index ed813c5c..bfe09ced 100644 --- a/openflexure_microscope/config.py +++ b/openflexure_microscope/config.py @@ -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_EXTENSIONS_PATH = os.path.join(USER_CONFIG_DIR, "microscope_extensions", "__init__.py") +USER_EXTENSIONS_PATH = os.path.join(USER_CONFIG_DIR, "microscope_extensions") # Load the default config with open(DEFAULT_CONFIG_FILE_PATH, "r") as default_rc: