Merge branch 'fix-simulation' into 'v3'

Simulation fixes

See merge request openflexure/openflexure-microscope-server!279
This commit is contained in:
Julian Stirling 2025-06-05 10:35:53 +00:00
commit 16317bf94c
6 changed files with 37 additions and 32 deletions

4
.gitignore vendored
View file

@ -79,8 +79,8 @@ packages.png
openflexure_microscope/cobertura.xml openflexure_microscope/cobertura.xml
# labthings settings # labthings settings
/settings/ settings/
/openflexure_settings/ openflexure_settings/
# web app build # web app build
/src/openflexure_microscope_server/static/ /src/openflexure_microscope_server/static/

View file

@ -11,5 +11,6 @@
"/background_detect/": "openflexure_microscope_server.things.background_detect:BackgroundDetectThing", "/background_detect/": "openflexure_microscope_server.things.background_detect:BackgroundDetectThing",
"/capture/": "openflexure_microscope_server.things.capture:CaptureThing" "/capture/": "openflexure_microscope_server.things.capture:CaptureThing"
}, },
"settings_folder": "/var/openflexure/settings/" "settings_folder": "/var/openflexure/settings/",
"log_folder": "/var/openflexure/logs/"
} }

View file

@ -8,8 +8,9 @@
"/system_control/": "openflexure_microscope_server.things.system_control:SystemControlThing", "/system_control/": "openflexure_microscope_server.things.system_control:SystemControlThing",
"/settings/": "openflexure_microscope_server.things.settings_manager:SettingsManager", "/settings/": "openflexure_microscope_server.things.settings_manager:SettingsManager",
"/smart_scan/": "openflexure_microscope_server.things.smart_scan:SmartScanThing", "/smart_scan/": "openflexure_microscope_server.things.smart_scan:SmartScanThing",
"/background_detect/": "openflexure_microscope_server.things.smart_scan:BackgroundDetectThing", "/background_detect/": "openflexure_microscope_server.things.background_detect:BackgroundDetectThing",
"/api_test/": "openflexure_microscope_server.things.test:APITestThing" "/capture/": "openflexure_microscope_server.things.capture:CaptureThing"
}, },
"settings_folder": "./openflexure_settings/" "settings_folder": "./openflexure/settings/",
"log_folder": "./openflexure/logs/"
} }

View file

@ -8,8 +8,9 @@
"/system_control/": "openflexure_microscope_server.things.system_control:SystemControlThing", "/system_control/": "openflexure_microscope_server.things.system_control:SystemControlThing",
"/settings/": "openflexure_microscope_server.things.settings_manager:SettingsManager", "/settings/": "openflexure_microscope_server.things.settings_manager:SettingsManager",
"/smart_scan/": "openflexure_microscope_server.things.smart_scan:SmartScanThing", "/smart_scan/": "openflexure_microscope_server.things.smart_scan:SmartScanThing",
"/background_detect/": "openflexure_microscope_server.things.smart_scan:BackgroundDetectThing", "/background_detect/": "openflexure_microscope_server.things.background_detect:BackgroundDetectThing",
"/api_test/": "openflexure_microscope_server.things.test:APITestThing" "/capture/": "openflexure_microscope_server.things.capture:CaptureThing"
}, },
"settings_folder": "./openflexure_settings/" "settings_folder": "./openflexure/settings/",
"log_folder": "./openflexure/logs/"
} }

View file

@ -4,17 +4,19 @@ import os
from fastapi.responses import PlainTextResponse from fastapi.responses import PlainTextResponse
OFM_LOG_FOLDER = "/var/openflexure/logs/" OFM_LOG_FILE = None
OFM_LOG_FILE = os.path.join(OFM_LOG_FOLDER, "openflexure_microscope.log")
def configure_logging(): def configure_logging(log_folder):
root_logger = logging.getLogger() root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO) root_logger.setLevel(logging.INFO)
# Explictly make OFM_LOG_FILE a global so it can be updated based on log settings
global OFM_LOG_FILE
OFM_LOG_FILE = os.path.join(log_folder, "openflexure_microscope.log")
try: try:
if not os.path.exists(OFM_LOG_FOLDER): if not os.path.exists(log_folder):
os.makedirs(OFM_LOG_FOLDER) os.makedirs(log_folder)
handler = RotatingFileHandler( handler = RotatingFileHandler(
filename=OFM_LOG_FILE, filename=OFM_LOG_FILE,
mode="a", mode="a",
@ -38,7 +40,7 @@ def configure_logging():
def retrieve_log() -> PlainTextResponse: def retrieve_log() -> PlainTextResponse:
""" """
Returns logs since we started running the server, up to a maxiumum of Returns logs since we started running the server, up to a maximum of
250 messages. This log is the one shown in the UI and on the logging page. 250 messages. This log is the one shown in the UI and on the logging page.
It does not include any of the `uvicorn.access` logs as these are emmitted It does not include any of the `uvicorn.access` logs as these are emmitted
@ -57,6 +59,10 @@ def retrieve_log_from_file() -> PlainTextResponse:
Note this is read and then sent as otherwise it causes a RuntimeError if it Note this is read and then sent as otherwise it causes a RuntimeError if it
is written to while sending through FileResponse is written to while sending through FileResponse
""" """
if OFM_LOG_FILE is None:
raise RuntimeError(
"Cannot retrieve log file as logging directory hasn't been configured"
)
with open(OFM_LOG_FILE, "r", encoding="utf-8") as logfile: with open(OFM_LOG_FILE, "r", encoding="utf-8") as logfile:
full_log = logfile.read() full_log = logfile.read()
return PlainTextResponse(full_log) return PlainTextResponse(full_log)
@ -86,7 +92,6 @@ class OFMHandler(logging.Handler):
""" """
Emit will save the logged record to the log Emit will save the logged record to the log
""" """
# Basic filter for now that simply stops uvicorn.access logs # Basic filter for now that simply stops uvicorn.access logs
# These are the logs each time an API endpoint is accessed # These are the logs each time an API endpoint is accessed
# This is only the log for the UI. # This is only the log for the UI.

View file

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Optional from typing import Optional
from copy import copy
from labthings_fastapi.server import cli, ThingServer from labthings_fastapi.server import cli, ThingServer
import uvicorn import uvicorn
@ -9,14 +10,11 @@ from .legacy_api import add_v2_endpoints
from ..logging import configure_logging, retrieve_log, retrieve_log_from_file from ..logging import configure_logging, retrieve_log, retrieve_log_from_file
def customise_server(server: ThingServer): def customise_server(server: ThingServer, log_folder: str):
"""Customise the server with additional endpoints, etc.""" """Customise the server with additional endpoints, etc."""
configure_logging() configure_logging(log_folder)
add_v2_endpoints(server) add_v2_endpoints(server)
try: add_static_files(server.app)
add_static_files(server.app)
except RuntimeError:
print("Failed to add static files - you will have to do without them!")
# Add an endpoint to get the logs - (directly calling the FastAPI decorator) # Add an endpoint to get the logs - (directly calling the FastAPI decorator)
server.app.get("/log/")(retrieve_log) server.app.get("/log/")(retrieve_log)
@ -26,19 +24,21 @@ def customise_server(server: ThingServer):
def serve_from_cli(argv: Optional[list[str]] = None): def serve_from_cli(argv: Optional[list[str]] = None):
"""Start the server from the command line""" """Start the server from the command line"""
args = cli.parse_args(argv) args = cli.parse_args(argv)
log_config = copy(uvicorn.config.LOGGING_CONFIG)
log_config["loggers"]["uvicorn"]["propagate"] = True
log_config["loggers"]["uvicorn.access"]["propagate"] = True
try: try:
config, server = None, None
config = cli.config_from_args(args) config = cli.config_from_args(args)
log_folder = config.get("log_folder", "./openflexure/logs")
server = cli.server_from_config(config) server = cli.server_from_config(config)
customise_server(server) customise_server(server, log_folder)
uvicorn.run( uvicorn.run(
server.app, server.app,
host=args.host, host=args.host,
port=args.port, port=args.port,
log_config={ log_config=log_config,
"version": 1,
"disable_existing_loggers": False,
},
) )
except BaseException as e: except BaseException as e:
@ -54,10 +54,7 @@ def serve_from_cli(argv: Optional[list[str]] = None):
app, app,
host=args.host, host=args.host,
port=args.port, port=args.port,
log_config={ log_config=log_config,
"version": 1,
"disable_existing_loggers": False,
},
) )
else: else:
raise e raise e