diff --git a/ofm_config_full.json b/ofm_config_full.json index 0e2d9cae..a73e4e40 100644 --- a/ofm_config_full.json +++ b/ofm_config_full.json @@ -7,7 +7,12 @@ "/camera_stage_mapping/": "openflexure_microscope_server.things.camera_stage_mapping:CameraStageMapper", "/system_control/": "openflexure_microscope_server.things.system_control:SystemControlThing", "/settings/": "openflexure_microscope_server.things.settings_manager:SettingsManager", - "/smart_scan/": "openflexure_microscope_server.things.smart_scan:SmartScanThing", + "/smart_scan/": { + "class": "openflexure_microscope_server.things.smart_scan:SmartScanThing", + "kwargs": { + "scans_folder": "/var/openflexure/scans/" + } + }, "/background_detect/": "openflexure_microscope_server.things.background_detect:BackgroundDetectThing", "/capture/": "openflexure_microscope_server.things.capture:CaptureThing" }, diff --git a/ofm_config_simulation.json b/ofm_config_simulation.json index 67721c9b..f982a617 100644 --- a/ofm_config_simulation.json +++ b/ofm_config_simulation.json @@ -7,7 +7,12 @@ "/camera_stage_mapping/": "openflexure_microscope_server.things.camera_stage_mapping:CameraStageMapper", "/system_control/": "openflexure_microscope_server.things.system_control:SystemControlThing", "/settings/": "openflexure_microscope_server.things.settings_manager:SettingsManager", - "/smart_scan/": "openflexure_microscope_server.things.smart_scan:SmartScanThing", + "/smart_scan/": { + "class": "openflexure_microscope_server.things.smart_scan:SmartScanThing", + "kwargs": { + "scans_folder": "./openflexure/scans/" + } + }, "/background_detect/": "openflexure_microscope_server.things.background_detect:BackgroundDetectThing", "/capture/": "openflexure_microscope_server.things.capture:CaptureThing" }, diff --git a/ofm_config_stub.json b/ofm_config_stub.json index 99b51f8e..85aab42e 100644 --- a/ofm_config_stub.json +++ b/ofm_config_stub.json @@ -7,7 +7,12 @@ "/camera_stage_mapping/": "openflexure_microscope_server.things.camera_stage_mapping:CameraStageMapper", "/system_control/": "openflexure_microscope_server.things.system_control:SystemControlThing", "/settings/": "openflexure_microscope_server.things.settings_manager:SettingsManager", - "/smart_scan/": "openflexure_microscope_server.things.smart_scan:SmartScanThing", + "/smart_scan/": { + "class": "openflexure_microscope_server.things.smart_scan:SmartScanThing", + "kwargs": { + "scans_folder": "./openflexure/scans/" + } + }, "/background_detect/": "openflexure_microscope_server.things.background_detect:BackgroundDetectThing", "/capture/": "openflexure_microscope_server.things.capture:CaptureThing" }, diff --git a/src/openflexure_microscope_server/server/__init__.py b/src/openflexure_microscope_server/server/__init__.py index bcf997a3..4ac3de5a 100644 --- a/src/openflexure_microscope_server/server/__init__.py +++ b/src/openflexure_microscope_server/server/__init__.py @@ -10,17 +10,33 @@ from .legacy_api import add_v2_endpoints from ..logging import configure_logging, retrieve_log, retrieve_log_from_file -def customise_server(server: ThingServer, log_folder: str): +def customise_server(server: ThingServer, log_folder: str, scans_folder: Optional[str]): """Customise the server with additional endpoints, etc.""" configure_logging(log_folder) add_v2_endpoints(server) - add_static_files(server.app) + add_static_files(server.app, scans_folder) # Add an endpoint to get the logs - (directly calling the FastAPI decorator) server.app.get("/log/")(retrieve_log) server.app.get("/logfile/")(retrieve_log_from_file) +def _get_scans_dir(config: dict) -> Optional[str]: + """ + Read the config and return the scans directory. + + Return is None if there is no /smart_scan/ thing loaded. + """ + + if "/smart_scan/" in config["things"]: + try: + return config["things"]["/smart_scan/"]["kwargs"]["scans_folder"] + except KeyError as e: + msg = "Configuration error smart scan should have scans_folder kwarg set" + raise RuntimeError(msg) from e + return None + + def serve_from_cli(argv: Optional[list[str]] = None): """Start the server from the command line""" args = cli.parse_args(argv) @@ -32,8 +48,9 @@ def serve_from_cli(argv: Optional[list[str]] = None): try: config = cli.config_from_args(args) log_folder = config.get("log_folder", "./openflexure/logs") + scans_folder = _get_scans_dir(config) server = cli.server_from_config(config) - customise_server(server, log_folder) + customise_server(server, log_folder, scans_folder) uvicorn.run( server.app, host=args.host, diff --git a/src/openflexure_microscope_server/server/serve_static_files.py b/src/openflexure_microscope_server/server/serve_static_files.py index 4f5ad96c..123c6d3e 100644 --- a/src/openflexure_microscope_server/server/serve_static_files.py +++ b/src/openflexure_microscope_server/server/serve_static_files.py @@ -1,4 +1,5 @@ import os +from typing import Optional from fastapi.responses import FileResponse, RedirectResponse from fastapi.staticfiles import StaticFiles @@ -22,7 +23,7 @@ def add_static_file(app: FastAPI, fname: str, folder: str) -> None: ) -def add_static_files(app: FastAPI) -> None: +def add_static_files(app: FastAPI, scans_folder: Optional[str]) -> None: """Add the static files responsible for the webapp app to the FastAPI app app: The FastAPI app to add to, in this case the OpenFlexure server @@ -45,9 +46,13 @@ def add_static_files(app: FastAPI) -> None: name=f"static_{fname}", ) - # Mount the scan directory to .../scans/, to allow dzi viewing - app.mount( - "/scans/", - StaticFiles(directory="/var/openflexure/scans/"), - name="scans", - ) + # If scans folder is None, there is not smart scan thing. So nothing to mount. + if scans_folder is not None: + # Mount the scan directory to .../scans/, to allow dzi viewing + if not os.path.isdir(scans_folder): + os.makedirs(scans_folder) + app.mount( + "/scans/", + StaticFiles(directory=scans_folder), + name="scans", + ) diff --git a/src/openflexure_microscope_server/things/smart_scan.py b/src/openflexure_microscope_server/things/smart_scan.py index 7d819bb3..50a8c442 100644 --- a/src/openflexure_microscope_server/things/smart_scan.py +++ b/src/openflexure_microscope_server/things/smart_scan.py @@ -114,7 +114,8 @@ def _scan_running(method): class SmartScanThing(Thing): - def __init__(self): + def __init__(self, scans_folder): + self._scans_folder = scans_folder self._preview_stitch_popen = None self._preview_stitch_popen_lock = threading.Lock() self._scan_lock = threading.Lock() @@ -270,11 +271,8 @@ class SmartScanThing(Thing): @property def base_scan_dir(self) -> str: - """This directory will hold all the scans we do.""" - # TODO: This should be determined using sensible configuration. - # If the working directory is `/var/openflexure` this will result - # in scans being saved at `/var/openflexure/scans/` - return "scans" + """The path of the directory where the scans are saved.""" + return self._scans_folder @thing_property def latest_scan_name(self) -> Optional[str]: