Commit a8a3cafa authored by jtc42's avatar jtc42
Browse files

Restructured labthings

parent 206dd521
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ from openflexure_microscope.plugins import MicroscopePlugin
from openflexure_microscope.api.views import MicroscopeViewPlugin
from openflexure_microscope.api.utilities import JsonResponse

from openflexure_microscope.common.tasks import taskify
from openflexure_microscope.common.labthings_core.tasks import taskify

import os
import time
+10 −18
Original line number Diff line number Diff line
@@ -3,29 +3,24 @@
import time
import atexit
import logging
import sys
import os

from flask import Flask, jsonify, send_file, url_for
from flask import Flask, jsonify, send_file

from serial import SerialException
from datetime import datetime

from flask_cors import CORS

from openflexure_microscope.api.exceptions import JSONExceptionHandler
from openflexure_microscope.api.utilities import list_routes
from openflexure_microscope.api.utilities import list_routes, init_default_plugins

from openflexure_microscope.config import (
    settings_file_path,
    JSONEncoder,
    USER_PLUGINS_PATH,
)
from openflexure_microscope.api import v2

from openflexure_microscope.common.labthings.labthing import LabThing
from openflexure_microscope.common.labthings.find import registered_plugins
from openflexure_microscope.common.labthings.plugins import find_plugins
from openflexure_microscope.common.flask_labthings.labthing import LabThing
from openflexure_microscope.common.flask_labthings.plugins import find_plugins

from openflexure_microscope.api.microscope import default_microscope as api_microscope

@@ -36,14 +31,13 @@ is_gunicorn = "gunicorn" in os.environ.get("SERVER_SOFTWARE", "")

DEFAULT_LOGFILE = settings_file_path("openflexure_microscope.log")

logger = logging.getLogger()
if (__name__ == "__main__") or (not is_gunicorn):
    # If imported, but not by gunicorn
    print("Letting sys handle logs")
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
else:
    # Direct standard Python logging to file and console
    root = logging.getLogger()
    error_formatter = logging.Formatter(
        "[%(asctime)s] [%(threadName)s] [%(levelname)s] %(message)s"
    )
@@ -56,9 +50,9 @@ else:

    for handler in error_handlers:
        handler.setFormatter(error_formatter)
        root.addHandler(handler)
        logger.addHandler(handler)

    root.setLevel(logging.getLogger("gunicorn.error").level)
    logger.setLevel(logging.getLogger("gunicorn.error").level)


# Create flask app
@@ -71,9 +65,6 @@ app.json_encoder = JSONEncoder
# Enable CORS everywhere
CORS(app, resources=r"*")

# Make errors more API friendly
handler = JSONExceptionHandler(app)

# Build a labthing
labthing = LabThing(app, prefix="/api/v2")
labthing.description = "Test LabThing-based API for OpenFlexure Microscope"
@@ -83,6 +74,8 @@ labthing.title = f"OpenFlexure Microscope {api_microscope.name}"
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)

@@ -120,7 +113,7 @@ labthing.register_property(views.SnapshotStream)
for name, action in views.enabled_root_actions().items():
    view_class = action["view_class"]
    rule = action["rule"]
    labthing.add_resource(view_class, "/actions{rule}")
    labthing.add_resource(view_class, f"/actions{rule}")
    labthing.register_action(view_class)


@@ -159,7 +152,6 @@ def err_log():

# Automatically clean up microscope at exit
def cleanup():
    global api_microscope
    logging.debug("App teardown started...")
    logging.debug("Settling...")
    time.sleep(0.5)
+1 −5
Original line number Diff line number Diff line
@@ -28,11 +28,7 @@ except Exception as e:

# Initialise stage
logging.debug("Creating stage object...")
try:
    api_stage = SangaStage()
except Exception as e:
    logging.error(e)
    logging.warning("No valid stage hardware found. Falling back to mock stage!")

api_stage = MockStage()

# Attach devices to microscope
+30 −0
Original line number Diff line number Diff line
import logging
import os
import errno
from werkzeug.exceptions import BadRequest
from flask import url_for, Blueprint

@@ -95,3 +97,31 @@ def list_routes(app):
        output[url] = line

    return output


def create_file(config_path):
    if not os.path.exists(os.path.dirname(config_path)):
        try:
            os.makedirs(os.path.dirname(config_path))
        except OSError as exc:  # Guard against race condition
            if exc.errno != errno.EEXIST:
                raise


def init_default_plugins(plugin_path):
    global _DEFAULT_PLUGIN_INIT
    os.makedirs(os.path.dirname(plugin_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)

        logging.info("Populating {}...".format(plugin_path))
        with open(plugin_path, "w") as outfile:
            outfile.write(_DEFAULT_PLUGIN_INIT)


_DEFAULT_PLUGIN_INIT = """from openflexure_microscope.plugins.v2.autofocus import autofocus_plugin_v2
from openflexure_microscope.plugins.v2.scan import scan_plugin_v2

__plugins__ = [autofocus_plugin_v2, scan_plugin_v2]"""
 No newline at end of file
+0 −5
Original line number Diff line number Diff line
@@ -2,11 +2,6 @@
Top-level representation of enabled actions
"""

from flask import Blueprint, url_for, jsonify

from openflexure_microscope.api.utilities import blueprint_for_module
from openflexure_microscope.utilities import get_docstring, description_from_view

from . import camera, stage, system

_actions = {
Loading