Shahd1sayed's picture
Deploy v2: multimodal ensemble router (Framingham tabular + ECG ResNet)
0f12291 verified
Raw
History Blame Contribute Delete
2.05 kB
"""Server-side range validation for the Framingham tabular fields.
Blank / missing fields are skipped here (they get KNN-imputed downstream).
Only *provided* values are checked: they must parse as numbers and fall inside
clinically plausible bounds. Returns a list of human-readable error strings
(empty == valid).
"""
from __future__ import annotations
from typing import Any
# Binary / categorical fields use "choices"; continuous fields use min/max.
FIELD_SPECS: dict[str, dict[str, Any]] = {
"male": {"choices": {0, 1}},
"age": {"min": 1, "max": 120},
"education": {"choices": {1, 2, 3, 4}},
"currentSmoker": {"choices": {0, 1}},
"cigsPerDay": {"min": 0, "max": 100},
"BPMeds": {"choices": {0, 1}},
"prevalentStroke": {"choices": {0, 1}},
"prevalentHyp": {"choices": {0, 1}},
"diabetes": {"choices": {0, 1}},
"totChol": {"min": 50, "max": 700},
"sysBP": {"min": 50, "max": 300},
"diaBP": {"min": 30, "max": 200},
"BMI": {"min": 10, "max": 70},
"heartRate": {"min": 20, "max": 300},
"glucose": {"min": 20, "max": 700},
}
def validate_tabular(fields: dict[str, Any]) -> list[str]:
errors: list[str] = []
for name, spec in FIELD_SPECS.items():
raw = fields.get(name)
if raw is None or str(raw).strip() == "":
continue # blank -> imputed later, nothing to validate
try:
v = float(raw)
except (TypeError, ValueError):
errors.append(f"{name}: '{raw}' is not a number")
continue
if "choices" in spec and v not in spec["choices"]:
errors.append(f"{name}: must be one of {sorted(spec['choices'])} (got {raw})")
if "min" in spec and v < spec["min"]:
errors.append(f"{name}: must be >= {spec['min']} (got {raw})")
if "max" in spec and v > spec["max"]:
errors.append(f"{name}: must be <= {spec['max']} (got {raw})")
return errors