Spaces:
Runtime error
Runtime error
| # Backend | |
| FastAPI backend for the Variant Risk Explainer research demo. | |
| The backend loads a fine-tuned DNABERT-2 sequence-classification model once at | |
| startup and exposes `POST /analyze` and `POST /api/analyze` for DNA sequence | |
| risk prediction. | |
| The response also includes an explanation generated from the model | |
| probabilities, selected threshold, and prediction label. By default this is | |
| rule-based. You can optionally enable an OpenAI-powered explanation paragraph. | |
| This is for research/demo use only. It is not a clinical diagnostic system and | |
| must not be used for medical decisions. | |
| ## Setup | |
| From the repository root: | |
| ```bash | |
| cd backend | |
| python -m venv .venv | |
| source .venv/bin/activate | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| cp .env.example .env | |
| ``` | |
| ## Model Folder | |
| The final local model folder is: | |
| ```text | |
| training/training_model_files/ | |
| ``` | |
| That folder is intentionally ignored by Git because it contains large model | |
| files. For a self-contained Docker deployment, place a copy at: | |
| ```text | |
| models/final_model/ | |
| ``` | |
| Configure the model path in `backend/.env`: | |
| ```bash | |
| MODEL_DIR=../training/training_model_files | |
| MODEL_THRESHOLD=0.16 | |
| MODEL_MAX_LENGTH=512 | |
| MODEL_NAME=DNABERT-2 ClinVar 20k | |
| DEVICE=auto | |
| ``` | |
| `DEVICE=auto` selects CUDA, then MPS, then CPU. | |
| `MODEL_DIR` may also be a Hugging Face model repository ID: | |
| ```bash | |
| MODEL_DIR=your-username/variant-risk-dnabert2-20k | |
| ``` | |
| For a private model repository, provide `HF_TOKEN` as a secret. | |
| ## Optional OpenAI Explanation | |
| Do not paste your OpenAI API key into source code or `.env.example`. | |
| Paste it only into your local `backend/.env` file: | |
| ```bash | |
| USE_AI_EXPLANATION=true | |
| OPENAI_API_KEY=your_openai_api_key_here | |
| ``` | |
| Then restart the backend. If the OpenAI key is missing, the package is not | |
| installed, or the API call fails, the backend automatically falls back to the | |
| local rule-based explanation. | |
| ## Run | |
| From `backend/`: | |
| ```bash | |
| uvicorn app.main:app --reload | |
| ``` | |
| Open: | |
| ```text | |
| http://localhost:8000/docs | |
| ``` | |
| ## Health Check | |
| ```bash | |
| curl http://localhost:8000/health | |
| ``` | |
| The deployment alias is: | |
| ```bash | |
| curl http://localhost:8000/api/health | |
| ``` | |
| The response shows whether the model loaded, selected device, model source, | |
| threshold, and explanation availability. | |
| ## Analyze Example | |
| ```bash | |
| curl -X POST http://localhost:8000/analyze \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "variant_name": "GRCh38-example", | |
| "gene": "BRAF", | |
| "sequence": "ACGTACGTACGTACGTACGTACGTACGTACGT", | |
| "notes": "Demo request" | |
| }' | |
| ``` | |
| Python example: | |
| ```python | |
| import requests | |
| response = requests.post( | |
| "http://localhost:8000/analyze", | |
| json={ | |
| "variant_name": "GRCh38-example", | |
| "gene": "BRAF", | |
| "sequence": "ACGTACGTACGTACGTACGTACGTACGTACGT", | |
| }, | |
| timeout=30, | |
| ) | |
| print(response.json()) | |
| ``` | |
| ## Response Fields | |
| - `prediction_class`: `0` for benign/likely benign, `1` for pathogenic/likely pathogenic | |
| - `prediction_label`: human-readable label | |
| - `risk_level`: `Lower` or `Elevated` | |
| - `benign_probability`: class 0 probability | |
| - `pathogenic_probability`: class 1 probability | |
| - `threshold`: decision threshold, currently `0.16` | |
| - `sequence_length_used`: sequence length after optional center crop | |
| - `explanation`: plain-language explanation of the model output | |
| - `explanation_source`: `openai`, `rule-based`, or `rule-based-fallback` | |
| - `confidence_level`: rough confidence category based on model probability | |
| - `recommendation`: safe research/demo recommendation | |
| - `limitations`: important limitations to show users | |
| ## Explanation Layer | |
| The default explanation is generated by local backend rules. When | |
| `USE_AI_EXPLANATION=true`, the backend asks OpenAI to rewrite only the | |
| explanation paragraph in beginner-friendly language. The prediction, | |
| probabilities, threshold, confidence level, recommendation, and limitations stay | |
| controlled by backend logic. | |
| The wording is intentionally cautious because it is derived only from the model | |
| output, not from clinical review. | |
| ## Static Frontend | |
| The Docker build creates the Next.js static export and copies it into | |
| `backend/static/`. When that folder exists, FastAPI serves the frontend at `/`. | |
| API routes are registered before static file serving so `/api/health` and | |
| `/api/analyze` remain available. | |
| ## Safety Notice | |
| Predictions are experimental model outputs. They can be wrong, incomplete, | |
| biased by ClinVar labels, or invalid outside the training distribution. Do not | |
| use this backend for diagnosis, treatment, or clinical decision-making. | |