jwkoh94/bridge-adherence
BRIDGE Adherence Scorer (Hugging Face Docker Space)
A FastAPI app that serves a single-page frontend and JSON endpoints for the canonical GAM-BRIDGE adherence-trajectory model. Scoring runs server-side in Python; the browser only ever receives probabilities. Model weights are kept out of this public repo and are pulled at startup from a private Hugging Face model repo.
BRIDGE is a monotone-spline generalised additive model (a GAM, additive in the features) that returns a probability over four adherence trajectory groups for a single patient window: G1 gradual decline, G2 early discontinuation, G3 rapid decline, G4 persistent adherence.
Endpoints
GET /serves the frontend.GET /healthreturns{status, model_loaded, model_source, n_features}.POST /scorebody{"inputs": { ...base fields... }}returns{probs:{G1..G4}, top_group, top_group_label, top_contributions}. Blank systolic BP, LDL, or eGFR are Ridge-imputed server-side. Inputs are scored in memory and are not logged or stored.POST /counterfactualsame body; returns the within-model probability shift toward persistent adherence (G4) for each intervention lever (care continuity, reduce switching, reduce polypharmacy, BP control, LDL control, smoking cessation, and an all-combined), with the G4 odds ratio and anapplicableflag plus reason for floored or already-satisfied levers. This is exact within-model intervention sensitivity on the additive model, not a causal effect.GET /trajectoriesreturns the four aggregate group-mean coverage archetype curves with prevalences and descriptions.
How the weights stay private
The local model/ directory is gitignored and is only a test-time fallback for running on the research host. In production the Space pulls the model at startup from a private HF model repo using huggingface_hub.hf_hub_download with two Space secrets, BRIDGE_MODEL_REPO and HF_TOKEN (a read token for that private repo). No weights and no patient data are committed to this public repo; the only bundled data file is the aggregate trajectory curves.
Running locally (research host, no token)
Place model_posterior.pkl and ridge_imputer_coefs.json in ./model/, then:
pip install -r requirements.txt
uvicorn app:app --host 127.0.0.1 --port 7860Open http://127.0.0.1:7860. Hard test gates:
python scripts/test_parity.py # /score parity vs BridgeScorer to < 1e-6
python scripts/test_smoke.py # counterfactual + trajectory smoke testsThe aggregate trajectory curves are rebuilt with:
python scripts/build_trajectories.pyDeploy (the steps you run; placeholders in angle brackets)
1. Create a PRIVATE HF model repo and upload the weights
huggingface-cli login # paste a write token
huggingface-cli repo create bridge-model --type model --private
huggingface-cli upload <HF_USER>/bridge-model \
/path/to/model_posterior.pkl model_posterior.pkl --repo-type model
huggingface-cli upload <HF_USER>/bridge-model \
/path/to/ridge_imputer_coefs.json ridge_imputer_coefs.json --repo-type model2. Create a PUBLIC HF Docker Space and push this directory (without model/)
huggingface-cli repo create bridge-adherence --type space --space_sdk docker
git clone https://huggingface.co/spaces/<HF_USER>/bridge-adherence
cd bridge-adherence
# copy the hf_space/ contents here (model/ is gitignored, do NOT copy it)
cp -r /path/to/hf_space/{app.py,Dockerfile,requirements.txt,.gitignore,lib,static,scripts,README.md} .
git add -A
git commit -m "BRIDGE adherence scorer Docker Space"
git push3. Add Space secrets
In the Space, open Settings then Variables and secrets and add:
HF_TOKENa read token scoped to the private model repo.BRIDGE_MODEL_REPOset to<HF_USER>/bridge-model.
The Space rebuilds and pulls the weights at startup. Confirm GET /health shows "model_source":"private_hf_repo".
4. Point the github.io redirect at the Space
Edit webpage/index.html and replace the placeholder Space URL https://huggingface.co/spaces/<HF_USER>/bridge-adherence with the real one.
Notes
- CPU-only numpy scoring; no rapids, cudf, or xgboost in the image.
- CORS defaults to allowing all origins for this public read-only scorer; set the
ALLOW_ORIGINSenv var (comma-separated) to restrict it to your GitHub Pages origin plus localhost. - The model is reported following TRIPOD-AI.
- seed 42.
