File size: 2,901 Bytes
10b056e
 
 
 
 
 
 
 
9ead7fd
10b056e
 
 
 
 
9ead7fd
 
10b056e
 
 
 
 
 
 
 
 
 
9ead7fd
10b056e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9ead7fd
 
 
 
 
 
 
 
 
 
 
10b056e
 
 
 
 
 
 
9ead7fd
10b056e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9ead7fd
 
 
 
 
 
 
 
10b056e
9ead7fd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""
MediScan AI — HuggingFace Space Backend
Port 7860 (required by HuggingFace Spaces)
"""

import uvicorn
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from contextlib import asynccontextmanager
from PIL import Image
import io

from model_loader import (
    load_pneumo_model, load_skin_models, load_diabetes_model,
    predict_pneumonia, predict_skin, predict_diabetes
)


@asynccontextmanager
async def lifespan(app: FastAPI):
    print("=" * 50)
    print("  MediScan AI Space — Loading models...")
    print("=" * 50)
    load_pneumo_model()
    load_skin_models()
    load_diabetes_model()
    print("=" * 50)
    print("  All models ready!")
    print("=" * 50)
    yield


app = FastAPI(
    title="MediScan AI",
    version="1.0.0",
    lifespan=lifespan,
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)


class DiabetesInput(BaseModel):
    pregnancies:       float
    glucose:           float
    blood_pressure:    float
    skin_thickness:    float
    insulin:           float
    bmi:               float
    diabetes_pedigree: float
    age:               float


@app.get("/")
def root():
    return {
        "status": "ok",
        "endpoints": {
            "pneumonia": "POST /predict/pneumonia",
            "skin":      "POST /predict/skin",
            "diabetes":  "POST /predict/diabetes",
            "docs":      "/docs",
        }
    }


@app.get("/health")
def health():
    return {"status": "healthy"}


@app.post("/predict/pneumonia")
async def pneumonia_endpoint(file: UploadFile = File(...)):
    if not file.content_type.startswith("image/"):
        raise HTTPException(400, "Must be an image file.")
    data = await file.read()
    try:
        image = Image.open(io.BytesIO(data))
    except Exception:
        raise HTTPException(400, "Could not read image.")
    try:
        return predict_pneumonia(image)
    except Exception as e:
        raise HTTPException(500, f"Inference error: {e}")


@app.post("/predict/skin")
async def skin_endpoint(file: UploadFile = File(...)):
    if not file.content_type.startswith("image/"):
        raise HTTPException(400, "Must be an image file.")
    data = await file.read()
    try:
        image = Image.open(io.BytesIO(data))
    except Exception:
        raise HTTPException(400, "Could not read image.")
    try:
        return predict_skin(image)
    except Exception as e:
        raise HTTPException(500, f"Inference error: {e}")


@app.post("/predict/diabetes")
async def diabetes_endpoint(payload: DiabetesInput):
    try:
        return predict_diabetes(payload.dict())
    except Exception as e:
        raise HTTPException(500, f"Inference error: {e}")


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=7860)