Sentoz commited on
Commit
a356dcd
·
verified ·
1 Parent(s): 41bb106

Deploy KidneyDL CT Scan Classifier

Browse files
Files changed (2) hide show
  1. app.py +24 -6
  2. src/cnnClassifier/pipeline/prediction.py +11 -11
app.py CHANGED
@@ -10,7 +10,21 @@ CORS(app)
10
  UPLOAD_FOLDER = "uploads"
11
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
12
 
13
- MODEL_PATH = os.path.join("artifacts", "training", "model.h5")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
 
16
  @app.route("/", methods=["GET"])
@@ -20,12 +34,13 @@ def home():
20
 
21
  @app.route("/health", methods=["GET"])
22
  def health():
23
- model_exists = os.path.isfile(MODEL_PATH)
24
  return jsonify({
25
- "status": "ok" if model_exists else "degraded",
26
- "model_found": model_exists,
27
  "model_path": os.path.abspath(MODEL_PATH),
28
- }), 200 if model_exists else 503
 
29
 
30
 
31
  @app.route("/train", methods=["GET", "POST"])
@@ -36,6 +51,9 @@ def train():
36
 
37
  @app.route("/predict", methods=["POST"])
38
  def predict():
 
 
 
39
  if "file" not in request.files:
40
  return jsonify({"error": "No file uploaded"}), 400
41
 
@@ -46,7 +64,7 @@ def predict():
46
  filepath = os.path.join(UPLOAD_FOLDER, file.filename)
47
  try:
48
  file.save(filepath)
49
- pipeline = PredictionPipeline(filepath)
50
  result = pipeline.predict()
51
  return jsonify(result)
52
  except Exception as e:
 
10
  UPLOAD_FOLDER = "uploads"
11
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
12
 
13
+ # Resolve model path once — prefer .keras (Keras 3 native), fall back to .h5
14
+ _keras_path = os.path.join("artifacts", "training", "model.keras")
15
+ _h5_path = os.path.join("artifacts", "training", "model.h5")
16
+ MODEL_PATH = _keras_path if os.path.isfile(_keras_path) else _h5_path
17
+
18
+ # Load the model once at startup so every request reuses the same in-memory model
19
+ _MODEL = None
20
+ _MODEL_ERROR = None
21
+ try:
22
+ from tensorflow.keras.models import load_model
23
+ _MODEL = load_model(MODEL_PATH)
24
+ print(f"[startup] Model loaded from {MODEL_PATH}")
25
+ except Exception as _e:
26
+ _MODEL_ERROR = str(_e)
27
+ print(f"[startup] WARNING: model failed to load — {_MODEL_ERROR}")
28
 
29
 
30
  @app.route("/", methods=["GET"])
 
34
 
35
  @app.route("/health", methods=["GET"])
36
  def health():
37
+ ok = _MODEL is not None
38
  return jsonify({
39
+ "status": "ok" if ok else "degraded",
40
+ "model_loaded": ok,
41
  "model_path": os.path.abspath(MODEL_PATH),
42
+ "error": _MODEL_ERROR,
43
+ }), 200 if ok else 503
44
 
45
 
46
  @app.route("/train", methods=["GET", "POST"])
 
51
 
52
  @app.route("/predict", methods=["POST"])
53
  def predict():
54
+ if _MODEL is None:
55
+ return jsonify({"error": f"Model not loaded: {_MODEL_ERROR}"}), 503
56
+
57
  if "file" not in request.files:
58
  return jsonify({"error": "No file uploaded"}), 400
59
 
 
64
  filepath = os.path.join(UPLOAD_FOLDER, file.filename)
65
  try:
66
  file.save(filepath)
67
+ pipeline = PredictionPipeline(filepath, model=_MODEL)
68
  result = pipeline.predict()
69
  return jsonify(result)
70
  except Exception as e:
src/cnnClassifier/pipeline/prediction.py CHANGED
@@ -5,14 +5,19 @@ import os
5
 
6
 
7
  class PredictionPipeline:
8
- def __init__(self, filename):
9
  self.filename = filename
 
10
 
11
  def predict(self):
12
- keras_path = os.path.join("artifacts", "training", "model.keras")
13
- h5_path = os.path.join("artifacts", "training", "model.h5")
14
- model_path = keras_path if os.path.isfile(keras_path) else h5_path
15
- model = load_model(model_path)
 
 
 
 
16
 
17
  img = image.load_img(self.filename, target_size=(224, 224))
18
  img_array = image.img_to_array(img)
@@ -20,9 +25,4 @@ class PredictionPipeline:
20
 
21
  result = np.argmax(model.predict(img_array), axis=1)
22
 
23
- if result[0] == 1:
24
- prediction = "Tumor"
25
- else:
26
- prediction = "Normal"
27
-
28
- return [{"image": prediction}]
 
5
 
6
 
7
  class PredictionPipeline:
8
+ def __init__(self, filename, model=None):
9
  self.filename = filename
10
+ self._model = model
11
 
12
  def predict(self):
13
+ # Use pre-loaded model if provided, otherwise load from disk
14
+ if self._model is not None:
15
+ model = self._model
16
+ else:
17
+ keras_path = os.path.join("artifacts", "training", "model.keras")
18
+ h5_path = os.path.join("artifacts", "training", "model.h5")
19
+ model_path = keras_path if os.path.isfile(keras_path) else h5_path
20
+ model = load_model(model_path)
21
 
22
  img = image.load_img(self.filename, target_size=(224, 224))
23
  img_array = image.img_to_array(img)
 
25
 
26
  result = np.argmax(model.predict(img_array), axis=1)
27
 
28
+ return [{"image": "Tumor" if result[0] == 1 else "Normal"}]