"""Gradio demo for epibarrett BE/EAC methylation classifier.""" from __future__ import annotations import tempfile from pathlib import Path import gradio as gr import joblib import pandas as pd from huggingface_hub import hf_hub_download REPO_ID = "kmlyyll/epibarrett-model" BUNDLE_PATH = Path("epibarrett_model.joblib") def _load_bundle(): if not BUNDLE_PATH.exists(): hf_hub_download(REPO_ID, filename="epibarrett_model.joblib", local_dir=".") return joblib.load(BUNDLE_PATH) BUNDLE = _load_bundle() LASSO = BUNDLE["lasso"] PREPROCESSOR = BUNDLE["preprocessor"] PROBE_NAMES = BUNDLE["probe_names"] CLINICAL_FEATURES = BUNDLE["clinical_features"] def predict(csv_file): X = pd.read_csv(csv_file.name, index_col=0) missing = [p for p in PROBE_NAMES if p not in X.columns] if missing: raise gr.Error( f"Missing {len(missing)} expected probe columns (e.g. {missing[:5]})." ) M = PREPROCESSOR.transform(X[PROBE_NAMES]) proba = LASSO.predict_proba(M.to_numpy())[:, 1] out = pd.DataFrame( {"sample_id": X.index, "BE_EAC_probability": proba, "risk_call": (proba >= 0.5).astype(int)} ) tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".csv") out.to_csv(tmp.name, index=False) return out, tmp.name with gr.Blocks(title="epibarrett BE/EAC classifier") as demo: gr.Markdown( """ # epibarrett demo Upload a CSV of HM450-style beta values (rows = samples, columns = CpG probes). The model returns a calibrated probability of Barrett's esophagus / EAC for each sample. """ ) file_in = gr.File(label="Upload beta-value CSV", file_types=[".csv"]) btn = gr.Button("Predict") table_out = gr.Dataframe(label="Predictions") file_out = gr.File(label="Download predictions CSV") btn.click(fn=predict, inputs=file_in, outputs=[table_out, file_out]) if __name__ == "__main__": demo.launch()