From c32b44d1a6d14c542bf822ac3c483c19e6957e67 Mon Sep 17 00:00:00 2001 From: Richard Bowman Date: Fri, 9 Aug 2024 00:49:24 +0100 Subject: [PATCH] Refactor server into submodule --- src/openflexure_microscope_server/server.py | 71 ------------------- .../server/__init__.py | 43 +++++++++++ .../server/legacy_api.py | 35 +++++++++ .../{ => server}/serve_static_files.py | 0 4 files changed, 78 insertions(+), 71 deletions(-) delete mode 100644 src/openflexure_microscope_server/server.py create mode 100644 src/openflexure_microscope_server/server/__init__.py create mode 100644 src/openflexure_microscope_server/server/legacy_api.py rename src/openflexure_microscope_server/{ => server}/serve_static_files.py (100%) diff --git a/src/openflexure_microscope_server/server.py b/src/openflexure_microscope_server/server.py deleted file mode 100644 index ba0bdec0..00000000 --- a/src/openflexure_microscope_server/server.py +++ /dev/null @@ -1,71 +0,0 @@ -from __future__ import annotations -import logging -from fastapi import Response -from labthings_fastapi.thing_server import ThingServer -from labthings_sangaboard import SangaboardThing -from labthings_picamera2.thing import StreamingPiCamera2 -from socket import gethostname - -from .things.autofocus import AutofocusThing -from .things.camera_stage_mapping import CameraStageMapper -from .things.system_control import SystemControlThing -from .things.settings_manager import SettingsManager -from .things.auto_recentre_stage import RecentringThing -from .things.smart_scan import SmartScanThing, BackgroundDetectThing -from .things.stitching import Stitcher -from .things.test import APITestThing -from .serve_static_files import add_static_files -from .logging import configure_logging, retrieve_log - -configure_logging() - -thing_server = ThingServer() -thing_server.add_thing(StreamingPiCamera2(), "/camera/") -thing_server.add_thing(SangaboardThing(), "/stage/") -thing_server.add_thing(RecentringThing(), "/auto_recentre_stage/") -thing_server.add_thing(AutofocusThing(), "/autofocus/") -thing_server.add_thing(CameraStageMapper(), "/camera_stage_mapping/") -thing_server.add_thing(SystemControlThing(), "/system_control/") -thing_server.add_thing(SettingsManager(), "/settings/") -thing_server.add_thing(SmartScanThing("application/openflexure-stitching/.venv/bin/openflexure-stitch"), "/smart_scan/") -thing_server.add_thing(BackgroundDetectThing(), "/background_detect/") -thing_server.add_thing(APITestThing(), "/api_test/") -try: - add_static_files(thing_server.app) -except RuntimeError: - print("Failed to add static files - you will have to do without them!") - -# Add an endpoint to get the log -thing_server.app.get("/log/")(retrieve_log) - - -app = thing_server.app - -# TODO: update openflexure connect to make this unnecessary!! -# The endpoints below fool OpenFlexure Connect into thinking we are a -# v2 microscope, so we show up correctly. -# This is necessary until Connect is rebuilt. -@app.get("/routes") -def routes_stub() -> dict[str, dict]: - """A stub list of routes, used by OF Connect to identify the microscope""" - fake_routes = [ - "/api/v2/", - "/api/v2/streams/snapshot", - "/api/v2/instrument/settings/name" - ] - return {url: {"url": url, "methods": ["GET"]} for url in fake_routes} - -class JPEGResponse(Response): - media_type = "image/jpeg" - -@app.get("/api/v2/streams/snapshot") -@app.head("/api/v2/streams/snapshot") -async def thumbnail() -> JPEGResponse: - """A low-resolution snapshot, for compatibility with OF connect""" - blob = await thing_server.things["/camera/"].lores_mjpeg_stream.grab_frame() - return JPEGResponse(blob) - -@app.get("/api/v2/instrument/settings/name") -def get_hostname() -> str: - """Get the hostname of the device, for compatibility with OF connect""" - return gethostname() diff --git a/src/openflexure_microscope_server/server/__init__.py b/src/openflexure_microscope_server/server/__init__.py new file mode 100644 index 00000000..de55b1a0 --- /dev/null +++ b/src/openflexure_microscope_server/server/__init__.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +from labthings_fastapi.thing_server import ThingServer +from labthings_sangaboard import SangaboardThing +from labthings_picamera2.thing import StreamingPiCamera2 + +from ..things.autofocus import AutofocusThing +from ..things.camera_stage_mapping import CameraStageMapper +from ..things.system_control import SystemControlThing +from ..things.settings_manager import SettingsManager +from ..things.auto_recentre_stage import RecentringThing +from ..things.smart_scan import SmartScanThing, BackgroundDetectThing +from ..things.test import APITestThing +from .serve_static_files import add_static_files +from .legacy_api import add_v2_endpoints +from ..logging import configure_logging, retrieve_log + +configure_logging() + +thing_server = ThingServer() +thing_server.add_thing(StreamingPiCamera2(), "/camera/") +thing_server.add_thing(SangaboardThing(), "/stage/") +thing_server.add_thing(RecentringThing(), "/auto_recentre_stage/") +thing_server.add_thing(AutofocusThing(), "/autofocus/") +thing_server.add_thing(CameraStageMapper(), "/camera_stage_mapping/") +thing_server.add_thing(SystemControlThing(), "/system_control/") +thing_server.add_thing(SettingsManager(), "/settings/") +thing_server.add_thing(SmartScanThing("application/openflexure-stitching/.venv/bin/openflexure-stitch"), "/smart_scan/") +thing_server.add_thing(BackgroundDetectThing(), "/background_detect/") +thing_server.add_thing(APITestThing(), "/api_test/") +try: + add_static_files(thing_server.app) +except RuntimeError: + print("Failed to add static files - you will have to do without them!") + +add_v2_endpoints(thing_server) # Add the v2 endpoints for compatibility with OpenFlexure Connect + +# Add an endpoint to get the log +thing_server.app.get("/log/")(retrieve_log) + + +app = thing_server.app + diff --git a/src/openflexure_microscope_server/server/legacy_api.py b/src/openflexure_microscope_server/server/legacy_api.py new file mode 100644 index 00000000..509d30b3 --- /dev/null +++ b/src/openflexure_microscope_server/server/legacy_api.py @@ -0,0 +1,35 @@ +from . import ThingServer +from fastapi import Response +from socket import gethostname + + +def add_v2_endpoints(thing_server: ThingServer): + app = thing_server.app + # TODO: update openflexure connect to make this unnecessary!! + # The endpoints below fool OpenFlexure Connect into thinking we are a + # v2 microscope, so we show up correctly. + # This is necessary until Connect is rebuilt. + @app.get("/routes") + def routes_stub() -> dict[str, dict]: + """A stub list of routes, used by OF Connect to identify the microscope""" + fake_routes = [ + "/api/v2/", + "/api/v2/streams/snapshot", + "/api/v2/instrument/settings/name" + ] + return {url: {"url": url, "methods": ["GET"]} for url in fake_routes} + + class JPEGResponse(Response): + media_type = "image/jpeg" + + @app.get("/api/v2/streams/snapshot") + @app.head("/api/v2/streams/snapshot") + async def thumbnail() -> JPEGResponse: + """A low-resolution snapshot, for compatibility with OF connect""" + blob = await thing_server.things["/camera/"].lores_mjpeg_stream.grab_frame() + return JPEGResponse(blob) + + @app.get("/api/v2/instrument/settings/name") + def get_hostname() -> str: + """Get the hostname of the device, for compatibility with OF connect""" + return gethostname() diff --git a/src/openflexure_microscope_server/serve_static_files.py b/src/openflexure_microscope_server/server/serve_static_files.py similarity index 100% rename from src/openflexure_microscope_server/serve_static_files.py rename to src/openflexure_microscope_server/server/serve_static_files.py