web UI added and refactoring done
This commit is contained in:
@@ -24,20 +24,18 @@ _MAX_COMBOS = 4096
|
||||
|
||||
|
||||
def _require_int(payload: dict[str, Any], key: str, default: int) -> int:
|
||||
"""Read an integer field, rejecting JSON arrays/objects with a named ValueError.
|
||||
"""Read a strict JSON integer, treating an explicit ``null`` as 'use default'.
|
||||
|
||||
Bare ``int()`` raises ``TypeError`` on a list/dict, which escapes the
|
||||
config-error contract; surface it as a ValueError naming the field instead.
|
||||
Accept only a genuine JSON integer (not bool, not float, not numeric string):
|
||||
silently truncating ``5.7`` or parsing ``"5"`` would hide a malformed config.
|
||||
Mirrors ``run_config_codec._read_int`` so every config integer reads identically.
|
||||
"""
|
||||
value = payload.get(key, default)
|
||||
if value is None: # explicit JSON null -> use the default, never coerce
|
||||
return default
|
||||
if isinstance(value, bool) or not isinstance(value, (int, float, str)):
|
||||
if isinstance(value, bool) or not isinstance(value, int):
|
||||
raise ValueError(f"{key} must be a JSON integer")
|
||||
try:
|
||||
return int(value)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError(f"{key} must be a JSON integer") from exc
|
||||
return value
|
||||
|
||||
|
||||
def _require_str(payload: dict[str, Any], key: str, default: str) -> str:
|
||||
@@ -131,8 +129,8 @@ def validate_sweep_model(sweep: RadarSweepModel) -> None:
|
||||
raise ValueError("radar.sweep.points must be an integer")
|
||||
if points <= 0:
|
||||
raise ValueError("radar.sweep.points must be > 0")
|
||||
if float(sweep.stop_hz) < float(sweep.start_hz):
|
||||
raise ValueError("radar.sweep.stop_hz must be >= radar.sweep.start_hz")
|
||||
if float(sweep.stop_hz) <= float(sweep.start_hz):
|
||||
raise ValueError("radar.sweep.stop_hz must be > radar.sweep.start_hz")
|
||||
|
||||
|
||||
def validate_gpr_model(
|
||||
@@ -173,6 +171,34 @@ def validate_gpr_model(
|
||||
seen_input_positions.add(input_pos)
|
||||
|
||||
|
||||
def validate_combos(
|
||||
combos: list[ComboModel],
|
||||
*,
|
||||
input_positions: int,
|
||||
output_positions: int,
|
||||
) -> None:
|
||||
"""Validate run combos against the configured switch dimensions.
|
||||
|
||||
Each combo's input/output must index a real switch position, and no
|
||||
``input:output`` pair may repeat — an out-of-range or duplicate combo is a
|
||||
config error that would otherwise produce missing or doubled traces downstream.
|
||||
"""
|
||||
seen: set[tuple[int, int]] = set()
|
||||
for combo in combos:
|
||||
if not 0 <= int(combo.input) < int(input_positions):
|
||||
raise ValueError(
|
||||
f"run.combos input {combo.input} is out of range [0, {input_positions})"
|
||||
)
|
||||
if not 0 <= int(combo.output) < int(output_positions):
|
||||
raise ValueError(
|
||||
f"run.combos output {combo.output} is out of range [0, {output_positions})"
|
||||
)
|
||||
pair = (int(combo.input), int(combo.output))
|
||||
if pair in seen:
|
||||
raise ValueError(f"run.combos contains duplicate combo {combo.input}:{combo.output}")
|
||||
seen.add(pair)
|
||||
|
||||
|
||||
def parse_combos_from_text(text: str) -> list[ComboModel]:
|
||||
"""Parse UI combos string in `input:output,input:output` format."""
|
||||
cleaned = text.strip()
|
||||
|
||||
Reference in New Issue
Block a user