necst.web.operator_console¶
HTTP helpers for the NECST Operator Console.
This module is the thin boundary between the browser-facing Operator Console and the shared read-only status / operator action layers. It deliberately keeps validation and command dispatch small and explicit:
read-only status is built from
status_model;write-like actions are sent only through
necst.core.operator_actions;unimplemented or site-disabled actions are rejected before any telescope command can be sent.
- class ConsoleLogEntry(time, ok, message, action='', session_id='', data=<factory>)[source]¶
Bases:
objectOne operator-log line displayed in the browser and JSONL log.
- Parameters:
time (str) –
ok (bool) –
message (str) –
action (str) –
session_id (str) –
data (Dict[str, Any]) –
- time: str¶
- ok: bool¶
- message: str¶
- action: str = ''¶
- session_id: str = ''¶
- data: Dict[str, Any]¶
- class ConsoleAuthorityState(held=False, session_id=None, necst_held=False, necst_identity=None, mode='none', note='')[source]¶
Bases:
objectOperator-console authority state.
heldandsession_idare the browser/session gate. When running in live mode,necst_heldmeans this console process also holds actual NECST authority through a persistent Commander. Observation/RSky/SkyDip launchers run as separate processes, so the console must release actual authority before starting them to avoid blocking the child process.- Parameters:
held (bool) –
session_id (Optional[str]) –
necst_held (bool) –
necst_identity (Optional[str]) –
mode (str) –
note (str) –
- held: bool = False¶
- session_id: Optional[str] = None¶
- necst_held: bool = False¶
- necst_identity: Optional[str] = None¶
- mode: str = 'none'¶
- note: str = ''¶
- class OperatorConsoleState(telescope, progress_root, progress_url, progress_monitor=None, action_mode='live', live_actions_enabled=True, status_refresh_ms=1000, status_no_ros=False, quiet=False, events_limit=12, site_summary=<factory>, mount_limits=<factory>, site_capabilities=<factory>, chopper_config=<factory>, live_cache=None, observation_log=None, operator_log_path=None, launcher_log_dir=None, obs_roots=<factory>, process_registry=<factory>, log=<factory>, authority=<factory>, authority_handle=None, last_command_az=None, last_command_el=None, last_mount_target_az=None, last_mount_target_el=None, last_mount_target_started_at=None, last_mount_target_reached_since=None, last_safety_release_requested_at=None, last_manual_state='idle', last_active_task='none', last_observation_abort_requested_at=None, last_observation_stop_requested_at=None, last_observation_safety_labels=<factory>, last_chopper_state='unknown', last_chopper_position=None, shutdown_requested=False, cleanup_started_at=None, cleanup_finished_at=None, cleanup_status='not_started', cleanup_summary=<factory>, shutdown_terminate_launchers=True, shutdown_launcher_timeout_sec=3.0, shutdown_launcher_kill_timeout_sec=1.0, exclusive_start_action=None, exclusive_start_session_id=None, exclusive_start_started_at=None, exclusive_start_message='', safe_start=False, rescue_mode=False, local_state_reset_archive=None, local_state_reset_summary=<factory>, last_status_exception_message='', last_status_exception_at=None, node_health_cache=<factory>, node_health_checked_at_unix=0.0, last_node_health_event_key='', last_launcher_failure=<factory>, lock=<factory>)[source]¶
Bases:
objectMutable server state that is not part of NECST telemetry.
- Parameters:
telescope (str) –
progress_root (Path) –
progress_url (str) –
progress_monitor (Optional[ProgressMonitorManager]) –
action_mode (str) –
live_actions_enabled (bool) –
status_refresh_ms (int) –
status_no_ros (bool) –
quiet (bool) –
events_limit (int) –
site_summary (SiteConfigSummary) –
mount_limits (Dict[str, float]) –
site_capabilities (Dict[str, bool]) –
chopper_config (Dict[str, Any]) –
live_cache (Optional[LiveTelemetryCache]) –
observation_log (Optional[ObservationLogManager]) –
operator_log_path (Optional[Path]) –
launcher_log_dir (Optional[Path]) –
obs_roots (List[Path]) –
process_registry (ProcessRegistry) –
log (List[ConsoleLogEntry]) –
authority (ConsoleAuthorityState) –
authority_handle (Any) –
last_command_az (Optional[float]) –
last_command_el (Optional[float]) –
last_mount_target_az (Optional[float]) –
last_mount_target_el (Optional[float]) –
last_mount_target_started_at (Optional[float]) –
last_mount_target_reached_since (Optional[float]) –
last_safety_release_requested_at (Optional[float]) –
last_manual_state (str) –
last_active_task (str) –
last_observation_abort_requested_at (Optional[float]) –
last_observation_stop_requested_at (Optional[float]) –
last_observation_safety_labels (List[str]) –
last_chopper_state (str) –
last_chopper_position (Optional[float]) –
shutdown_requested (bool) –
cleanup_started_at (Optional[float]) –
cleanup_finished_at (Optional[float]) –
cleanup_status (str) –
cleanup_summary (Dict[str, Any]) –
shutdown_terminate_launchers (bool) –
shutdown_launcher_timeout_sec (float) –
shutdown_launcher_kill_timeout_sec (float) –
exclusive_start_action (Optional[str]) –
exclusive_start_session_id (Optional[str]) –
exclusive_start_started_at (Optional[float]) –
exclusive_start_message (str) –
safe_start (bool) –
rescue_mode (bool) –
local_state_reset_archive (Optional[str]) –
local_state_reset_summary (Dict[str, Any]) –
last_status_exception_message (str) –
last_status_exception_at (Optional[float]) –
node_health_cache (Dict[str, Any]) –
node_health_checked_at_unix (float) –
last_node_health_event_key (str) –
last_launcher_failure (Dict[str, Any]) –
lock (RLock) –
- telescope: str¶
- progress_root: Path¶
- progress_url: str¶
- progress_monitor: Optional[ProgressMonitorManager] = None¶
- action_mode: str = 'live'¶
- live_actions_enabled: bool = True¶
- status_refresh_ms: int = 1000¶
- status_no_ros: bool = False¶
- quiet: bool = False¶
- events_limit: int = 12¶
- site_summary: SiteConfigSummary¶
- mount_limits: Dict[str, float]¶
- site_capabilities: Dict[str, bool]¶
- chopper_config: Dict[str, Any]¶
- live_cache: Optional[LiveTelemetryCache] = None¶
- observation_log: Optional[ObservationLogManager] = None¶
- operator_log_path: Optional[Path] = None¶
- launcher_log_dir: Optional[Path] = None¶
- obs_roots: List[Path]¶
- process_registry: ProcessRegistry¶
- log: List[ConsoleLogEntry]¶
- authority: ConsoleAuthorityState¶
- authority_handle: Any = None¶
- last_command_az: Optional[float] = None¶
- last_command_el: Optional[float] = None¶
- last_mount_target_az: Optional[float] = None¶
- last_mount_target_el: Optional[float] = None¶
- last_mount_target_started_at: Optional[float] = None¶
- last_mount_target_reached_since: Optional[float] = None¶
- last_safety_release_requested_at: Optional[float] = None¶
- last_manual_state: str = 'idle'¶
- last_active_task: str = 'none'¶
- last_observation_abort_requested_at: Optional[float] = None¶
- last_observation_stop_requested_at: Optional[float] = None¶
- last_observation_safety_labels: List[str]¶
- last_chopper_state: str = 'unknown'¶
- last_chopper_position: Optional[float] = None¶
- shutdown_requested: bool = False¶
- cleanup_started_at: Optional[float] = None¶
- cleanup_finished_at: Optional[float] = None¶
- cleanup_status: str = 'not_started'¶
- cleanup_summary: Dict[str, Any]¶
- shutdown_terminate_launchers: bool = True¶
- shutdown_launcher_timeout_sec: float = 3.0¶
- shutdown_launcher_kill_timeout_sec: float = 1.0¶
- exclusive_start_action: Optional[str] = None¶
- exclusive_start_session_id: Optional[str] = None¶
- exclusive_start_started_at: Optional[float] = None¶
- exclusive_start_message: str = ''¶
- safe_start: bool = False¶
- rescue_mode: bool = False¶
- local_state_reset_archive: Optional[str] = None¶
- local_state_reset_summary: Dict[str, Any]¶
- last_status_exception_message: str = ''¶
- last_status_exception_at: Optional[float] = None¶
- node_health_cache: Dict[str, Any]¶
- node_health_checked_at_unix: float = 0.0¶
- last_node_health_event_key: str = ''¶
- last_launcher_failure: Dict[str, Any]¶
- lock: RLock¶
- resolve_site_summary(*, site_config_path=None, az_min=None, az_max=None, el_min=None, el_max=None)[source]¶
Resolve active site settings for console display and validation.
- Parameters:
site_config_path (Optional[Union[PathLike[str], str]]) –
az_min (Optional[float]) –
az_max (Optional[float]) –
el_min (Optional[float]) –
el_max (Optional[float]) –
- Return type:
- resolve_mount_limits(*, az_min=None, az_max=None, el_min=None, el_max=None, site_config_path=None)[source]¶
Resolve mount limits from site config, then CLI fallback values.
- Parameters:
az_min (Optional[float]) –
az_max (Optional[float]) –
el_min (Optional[float]) –
el_max (Optional[float]) –
site_config_path (Optional[Union[PathLike[str], str]]) –
- Return type:
Dict[str, float]
- validate_mount_target(params, mount_limits)[source]¶
Validate mount mechanical Az/El in degrees using site TOML limits.
- Parameters:
params (Mapping[str, Any]) –
mount_limits (Mapping[str, Any]) –
- Return type:
Tuple[float, float]
- validate_observation_selection(params)[source]¶
Static obs-file selection validation; does not touch hardware.
- Parameters:
params (Mapping[str, Any]) –
- Return type:
Tuple[str, str, Optional[int]]
- resolve_obs_roots(configured_roots=None)[source]¶
Return NECST-side browse roots for preview and obs selection.
If
--obs-rootorNECST_CONSOLE_OBS_ROOTSis supplied, those paths define the chooser locations. Otherwise the console provides practical defaults visible to the process running the console, including Home, common obs/data directories, the current directory, and/. This makes the chooser usable without command-line options while still allowing a site to restrict it explicitly.- Parameters:
configured_roots (Optional[List[os.PathLike[str] | str]]) –
- Return type:
List[Path]
- list_server_obs_files(roots, directory='')[source]¶
- Parameters:
roots (List[Path]) –
directory (str) –
- Return type:
Dict[str, Any]
- preview_server_obs_file(roots, path, *, max_bytes=65536)[source]¶
- Parameters:
roots (List[Path]) –
path (str) –
max_bytes (int) –
- Return type:
Dict[str, Any]
- validate_site_capability(state, capability, *, action_label=None)[source]¶
Reject actions disabled by the active site config before command dispatch.
- Parameters:
state (OperatorConsoleState) –
capability (str) –
action_label (Optional[str]) –
- Return type:
None
- chopper_dry_run_payload(state, command)[source]¶
Return dry-run details using configured chopper endpoints.
- Parameters:
state (OperatorConsoleState) –
command (str) –
- Return type:
Dict[str, Any]
- run_self_check(state, *, include_progress_health=True)[source]¶
Run read-only console self-checks without sending telescope commands.
- Parameters:
state (OperatorConsoleState) –
include_progress_health (bool) –
- Return type:
Dict[str, Any]
- reset_local_console_state_files(*, progress_root, operator_log_dir, reason='operator request')[source]¶
Archive only local console/progress state files.
This never sends telescope, recorder, spectrometer, or ROS commands. It is intentionally limited to files that can make the web console believe a stale observation is still current after an interrupted previous run.
- Parameters:
progress_root (os.PathLike[str] | str) –
operator_log_dir (os.PathLike[str] | str) –
reason (str) –
- Return type:
Dict[str, Any]
- dispatch_action(state, action, params, session_id)[source]¶
Validate and dispatch one browser action.
Return
(ok, message, data). Invalid or not-yet-connected actions returnok=Falsebefore any operator command is sent.- Parameters:
state (OperatorConsoleState) –
action (str) –
params (Mapping[str, Any]) –
session_id (str) –
- Return type:
Tuple[bool, str, Dict[str, Any]]
- build_minimal_rescue_status(state, exc)[source]¶
Return a status payload that is deliberately hard to break.
The browser must keep showing STOP/ABORT and local recovery controls even if the normal status builder has a bug or a corrupted local pointer file.
- Parameters:
state (OperatorConsoleState) –
exc (BaseException) –
- Return type:
Dict[str, Any]
- build_console_status(state)[source]¶
- Parameters:
state (OperatorConsoleState) –
- Return type:
Dict[str, Any]
- load_demo_html(status_refresh_ms=1000)[source]¶
Load the v7 demo HTML so the real console keeps the approved layout.
- Parameters:
status_refresh_ms (int) –
- Return type:
str
- class OperatorConsoleHTTPServer(server_address, handler_class, *, state, html=None)[source]¶
Bases:
ThreadingHTTPServer- Parameters:
server_address (Tuple[str, int]) –
handler_class (type[BaseHTTPRequestHandler]) –
state (OperatorConsoleState) –
html (Optional[str]) –
- daemon_threads = True¶
- allow_reuse_address = True¶
- class OperatorConsoleHandler(request, client_address, server)[source]¶
Bases:
BaseHTTPRequestHandler- Parameters:
server (OperatorConsoleHTTPServer) –
- server: OperatorConsoleHTTPServer¶
- log_message(fmt, *args)[source]¶
Log an arbitrary message.
This is used by all other logging functions. Override it if you have specific logging wishes.
The first argument, FORMAT, is a format string for the message to be logged. If the format string contains any % escapes requiring parameters, they should be specified as subsequent arguments (it’s just like printf!).
The client ip and current date/time are prefixed to every message.
Unicode control characters are replaced with escaped hex before writing the output to stderr.
- Parameters:
fmt (str) –
args (Any) –
- Return type:
None
- run_server(*, host, port, telescope, progress_root, progress_url, progress_host='127.0.0.1', progress_port=8091, progress_refresh_ms=500, progress_no_ros=False, progress_log_dir=None, obs_roots=None, status_no_ros=False, action_mode='live', live_actions_enabled=True, status_refresh_ms=1000, quiet=False, open_browser=False, events_limit=12, site_config_path=None, operator_log_dir=None, launcher_log_dir=None, obslog_dir=None, obslog_prefix=None, obslog_user=None, shutdown_terminate_launchers=True, shutdown_launcher_timeout_sec=3.0, shutdown_launcher_kill_timeout_sec=1.0, safe_start=False, reset_local_state=False, rescue=False, az_min=None, az_max=None, el_min=None, el_max=None, stop_event=None)[source]¶
- Parameters:
host (str) –
port (int) –
telescope (str) –
progress_root (Path) –
progress_url (str) –
progress_host (str) –
progress_port (int) –
progress_refresh_ms (int) –
progress_no_ros (bool) –
progress_log_dir (Optional[Union[PathLike[str], str]]) –
obs_roots (Optional[List[os.PathLike[str] | str]]) –
status_no_ros (bool) –
action_mode (str) –
live_actions_enabled (bool) –
status_refresh_ms (int) –
quiet (bool) –
open_browser (bool) –
events_limit (int) –
site_config_path (Optional[Union[PathLike[str], str]]) –
operator_log_dir (Optional[Union[PathLike[str], str]]) –
launcher_log_dir (Optional[Union[PathLike[str], str]]) –
obslog_dir (Optional[Union[PathLike[str], str]]) –
obslog_prefix (Optional[str]) –
obslog_user (Optional[str]) –
shutdown_terminate_launchers (bool) –
shutdown_launcher_timeout_sec (float) –
shutdown_launcher_kill_timeout_sec (float) –
safe_start (bool) –
reset_local_state (bool) –
rescue (bool) –
az_min (Optional[float]) –
az_max (Optional[float]) –
el_min (Optional[float]) –
el_max (Optional[float]) –
stop_event (Optional[Event]) –
- Return type:
int