More typing fixes
This commit is contained in:
parent
8890590551
commit
18e89aa148
2 changed files with 34 additions and 15 deletions
|
|
@ -13,7 +13,9 @@ from uvicorn.main import Server
|
||||||
|
|
||||||
import labthings_fastapi as lt
|
import labthings_fastapi as lt
|
||||||
from labthings_fastapi.server import fallback
|
from labthings_fastapi.server import fallback
|
||||||
|
from labthings_fastapi.server.config_model import ThingServerConfig
|
||||||
|
|
||||||
|
from openflexure_microscope_server.things.camera import BaseCamera
|
||||||
from openflexure_microscope_server.utilities import load_patched_config
|
from openflexure_microscope_server.utilities import load_patched_config
|
||||||
|
|
||||||
from ..logging import configure_logging, retrieve_log, retrieve_log_from_file
|
from ..logging import configure_logging, retrieve_log, retrieve_log_from_file
|
||||||
|
|
@ -44,7 +46,9 @@ def set_shutdown_function(shutdown_function: Callable[[], None]) -> None:
|
||||||
shutdown_function()
|
shutdown_function()
|
||||||
original_handler(*args, **kwargs)
|
original_handler(*args, **kwargs)
|
||||||
|
|
||||||
Server.handle_exit = handle_exit
|
# Ignore the MyPy doesn't want us monkey patching. We have to unless the
|
||||||
|
# FastAPI lifecycle is fixed.
|
||||||
|
Server.handle_exit = handle_exit # type: ignore[method-assign]
|
||||||
|
|
||||||
|
|
||||||
def customise_server(
|
def customise_server(
|
||||||
|
|
@ -82,21 +86,24 @@ def serve_from_cli(argv: Optional[list[str]] = None) -> None:
|
||||||
log_config["loggers"]["uvicorn"]["propagate"] = True
|
log_config["loggers"]["uvicorn"]["propagate"] = True
|
||||||
log_config["loggers"]["uvicorn.access"]["propagate"] = True
|
log_config["loggers"]["uvicorn.access"]["propagate"] = True
|
||||||
|
|
||||||
# Create server and config vars before trying to configure so they are defined
|
# Create server and lt_config vars before trying to configure so they are defined
|
||||||
# if fallback is needed before they are set.
|
# if fallback is needed before they are set.
|
||||||
config = None
|
lt_config = None
|
||||||
server = None
|
server = None
|
||||||
try:
|
try:
|
||||||
config = _full_config_from_args(args)
|
lt_config, internal_config = _full_config_from_args(args)
|
||||||
log_folder = config.pop("log_folder", "./openflexure/logs")
|
|
||||||
scans_folder = _get_scans_dir(config)
|
server = lt.ThingServer.from_config(lt_config)
|
||||||
server = lt.ThingServer.from_config(config)
|
customise_server(
|
||||||
customise_server(server, log_folder, scans_folder)
|
server, internal_config["log_folder"], internal_config["scans_folder"]
|
||||||
|
)
|
||||||
|
|
||||||
def shutdown_call() -> None:
|
def shutdown_call() -> None:
|
||||||
try:
|
try:
|
||||||
# Kill any mjpeg streams so that StreamingResponses close.
|
camera_thing = server.things["camera"]
|
||||||
server.things["camera"].kill_mjpeg_streams()
|
if not isinstance(camera_thing, BaseCamera):
|
||||||
|
raise RuntimeError("Camera thing is not a BaseCamera")
|
||||||
|
camera_thing.kill_mjpeg_streams()
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
# Catch anything and log as it is essential that this
|
# Catch anything and log as it is essential that this
|
||||||
# function cannot raise an unhandled exception or Uvicorn
|
# function cannot raise an unhandled exception or Uvicorn
|
||||||
|
|
@ -122,7 +129,7 @@ def serve_from_cli(argv: Optional[list[str]] = None) -> None:
|
||||||
print(f"Error: {e}") # noqa: T201
|
print(f"Error: {e}") # noqa: T201
|
||||||
print("Starting fallback server.") # noqa: T201
|
print("Starting fallback server.") # noqa: T201
|
||||||
app = fallback.app
|
app = fallback.app
|
||||||
app.labthings_config = config
|
app.labthings_config = lt_config
|
||||||
app.labthings_server = server
|
app.labthings_server = server
|
||||||
app.labthings_error = e
|
app.labthings_error = e
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
|
|
@ -135,14 +142,25 @@ def serve_from_cli(argv: Optional[list[str]] = None) -> None:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
def _full_config_from_args(args: Namespace) -> dict:
|
def _full_config_from_args(args: Namespace) -> tuple[ThingServerConfig, dict[str, Any]]:
|
||||||
"""Load configuration from LabThings args allowing patching.
|
"""Load configuration from LabThings args allowing patching.
|
||||||
|
|
||||||
|
This returns the labthings ThingServerConfig model and a dictionary of the config
|
||||||
|
for the microscope.
|
||||||
|
|
||||||
This provides similar functionarlity to lt.cli.config_from_args except allows the
|
This provides similar functionarlity to lt.cli.config_from_args except allows the
|
||||||
configuration file to specify a base config, and optionally patches.
|
configuration file to specify a base config, and optionally patches.
|
||||||
"""
|
"""
|
||||||
|
internal_config = {"log_folder": "./openflexure/logs", "scans_folder": None}
|
||||||
# If no config file specified let LabThings handle it.
|
# If no config file specified let LabThings handle it.
|
||||||
if not args.config:
|
if not args.config:
|
||||||
return lt.cli.config_from_args(args)
|
return lt.cli.config_from_args(args), internal_config
|
||||||
|
|
||||||
return load_patched_config(args.config)
|
patched_config = load_patched_config(args.config)
|
||||||
|
log_folder = patched_config.pop("log_folder", None)
|
||||||
|
if log_folder is not None:
|
||||||
|
internal_config["log_folder"] = log_folder
|
||||||
|
scans_folder = _get_scans_dir(patched_config)
|
||||||
|
if scans_folder is not None:
|
||||||
|
internal_config["log_folder"] = log_folder
|
||||||
|
return ThingServerConfig(**patched_config), internal_config
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from fastapi import FastAPI
|
||||||
# Import as ofm server to attempt to minimise confusion with server as a var in other
|
# Import as ofm server to attempt to minimise confusion with server as a var in other
|
||||||
# functions and also FastAPI `Server`.
|
# functions and also FastAPI `Server`.
|
||||||
from openflexure_microscope_server import server as ofm_server
|
from openflexure_microscope_server import server as ofm_server
|
||||||
|
from openflexure_microscope_server.things.camera import BaseCamera
|
||||||
|
|
||||||
from .test_server_config import FULL_CONFIG
|
from .test_server_config import FULL_CONFIG
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ def test_successful_start(mocker, caplog):
|
||||||
mock_server = mocker.Mock()
|
mock_server = mocker.Mock()
|
||||||
# Create a mock for the camera so we can check the MJPEG streams are closed on
|
# Create a mock for the camera so we can check the MJPEG streams are closed on
|
||||||
# shutdown.
|
# shutdown.
|
||||||
mock_camera = mocker.Mock()
|
mock_camera = mocker.Mock(spec=BaseCamera)
|
||||||
mock_server.things = {"camera": mock_camera}
|
mock_server.things = {"camera": mock_camera}
|
||||||
# Mock the LabThings function that returns the server so we have a mock server
|
# Mock the LabThings function that returns the server so we have a mock server
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue