Mikecode123 commited on
Commit
eb052a3
·
verified ·
1 Parent(s): a1b7ef0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -83
app.py CHANGED
@@ -1,90 +1,80 @@
1
- import sys
2
- from pathlib import Path
3
-
4
-
5
- def _find_backend_path() -> Path:
6
- current = Path(__file__).resolve().parent
7
- for parent in [current] + list(current.parents):
8
- candidate = parent / "backend"
9
- if candidate.is_dir():
10
- return candidate
11
- raise RuntimeError("Could not find backend directory in parent paths")
12
-
13
- BACKEND_PATH = str(_find_backend_path())
14
- if BACKEND_PATH not in sys.path:
15
- sys.path.insert(0, BACKEND_PATH)
16
-
17
- from fastapi import FastAPI, UploadFile, File, HTTPException, Query
18
- from fastapi.middleware.cors import CORSMiddleware
19
- from app.models.model_manager import get_model_manager, MODEL_CONFIGS, ENSEMBLE_CONFIGS
20
-
21
- app = FastAPI(
22
- title="NeuroHealth Alzheimer MRI Space",
23
- version="1.0.0",
24
- description="FastAPI wrapper for Alzheimer's MRI models stored in backend/saved_models.",
25
- )
26
-
27
- app.add_middleware(
28
- CORSMiddleware,
29
- allow_origins=["*"],
30
- allow_credentials=True,
31
- allow_methods=["*"],
32
- allow_headers=["*"],
33
- )
34
-
35
- model_manager = get_model_manager()
36
- AD_KEYS = {"ad_dn121", "ad_dn169", "ad_dn201", "ad_homogeneous"}
37
-
38
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  @app.get("/")
40
- async def root():
41
- return {
42
- "message": "NeuroHealth Alzheimer MRI Space",
43
- "supported_endpoints": ["/health", "/models", "/predict/image"],
44
- }
45
 
46
 
47
- @app.get("/health")
48
- async def health():
49
- statuses = model_manager.get_model_status()
50
- return {
51
- "status": "ok",
52
- "model_status": {k: v for k, v in statuses.items() if k in AD_KEYS},
53
- "available_models": [m["key"] for m in model_manager.get_available_models("alzheimers")],
54
- }
55
-
56
-
57
- @app.get("/models")
58
- async def get_models():
59
- models = model_manager.get_available_models("alzheimers")
60
- models.append({
61
- "key": "ad_homogeneous",
62
- "name": "Alzheimer's MRI Homogeneous Ensemble (DenseNet 121+169+201)",
63
- "condition": "alzheimers",
64
- "imaging_type": "mri",
65
- "type": "ensemble",
66
- })
67
- return {"models": models}
68
-
69
-
70
- @app.post("/predict/image")
71
- async def predict_image(
72
- model_key: str = Query(..., description="Model key such as ad_dn121 or ad_homogeneous"),
73
- file: UploadFile = File(...),
74
- ):
75
- if model_key not in AD_KEYS:
76
- raise HTTPException(status_code=400, detail=f"Unknown Alzheimer MRI model key: {model_key}")
77
 
78
- image_bytes = await file.read()
79
- filename = file.filename or ""
80
- config = MODEL_CONFIGS.get(model_key, {})
81
 
82
- if model_key == "ad_homogeneous":
83
- result = model_manager.predict_ensemble(model_key, image_bytes, filename)
84
- else:
85
- result = model_manager.predict_image(model_key, image_bytes, filename)
86
 
87
- if "error" in result:
88
- raise HTTPException(status_code=400, detail=result["error"])
89
 
90
- return result
 
 
 
 
1
+ import torch
2
+ import torchvision.models as models
3
+ import torch.nn as nn
4
+ from fastapi import FastAPI, UploadFile, File, HTTPException
5
+ from PIL import Image
6
+ import io
7
+ import torchvision.transforms as transforms
8
+
9
+ app = FastAPI(title="Alzheimer MRI API")
10
+
11
+ DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
12
+
13
+
14
+ # -----------------------------
15
+ # MODEL LOADER
16
+ # -----------------------------
17
+ def load_model(path, num_classes=3):
18
+ model = models.densenet121(weights=None)
19
+ model.classifier = nn.Linear(model.classifier.in_features, num_classes)
20
+ model.load_state_dict(torch.load(path, map_location=DEVICE))
21
+ model.to(DEVICE)
22
+ model.eval()
23
+ return model
24
+
25
+
26
+ # -----------------------------
27
+ # LOAD ALL MODELS
28
+ # -----------------------------
29
+ MODELS = {
30
+ "ad_dn121": load_model("alzheimers_densenet121.pth"),
31
+ "ad_dn169": load_model("alzheimers_densenet169.pth"),
32
+ "ad_dn201": load_model("alzheimers_densenet201.pth"),
33
+ }
34
+
35
+
36
+ # -----------------------------
37
+ # IMAGE TRANSFORM
38
+ # -----------------------------
39
+ transform = transforms.Compose([
40
+ transforms.Resize((224, 224)),
41
+ transforms.ToTensor(),
42
+ ])
43
+
44
+
45
+ # -----------------------------
46
+ # PREDICTION FUNCTION
47
+ # -----------------------------
48
+ def predict(model, image_bytes):
49
+ image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
50
+ image = transform(image).unsqueeze(0).to(DEVICE)
51
+
52
+ with torch.no_grad():
53
+ outputs = model(image)
54
+ probs = torch.softmax(outputs, dim=1)
55
+
56
+ return probs[0].tolist()
57
+
58
+
59
+ # -----------------------------
60
+ # ROUTES
61
+ # -----------------------------
62
  @app.get("/")
63
+ def home():
64
+ return {"message": "Alzheimer MRI API is running"}
 
 
 
65
 
66
 
67
+ @app.post("/predict")
68
+ async def predict_image(model_key: str, file: UploadFile = File(...)):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
+ if model_key not in MODELS:
71
+ raise HTTPException(status_code=400, detail="Invalid model key")
 
72
 
73
+ image_bytes = await file.read()
 
 
 
74
 
75
+ result = predict(MODELS[model_key], image_bytes)
 
76
 
77
+ return {
78
+ "model": model_key,
79
+ "prediction": result
80
+ }