Rizwan9 commited on
Commit
02cb96d
·
verified ·
1 Parent(s): f981030

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -30
app.py CHANGED
@@ -1,55 +1,70 @@
1
  from flask import Flask, request, jsonify, make_response
2
- import joblib, pandas as pd, numpy as np, os, time, sys
3
 
4
- print("==> [BOOT] Starting app.py", flush=True)
5
  app = Flask(__name__)
6
 
7
- MODEL_PATH = os.getenv("MODEL_PATH", "superkart_sales_forecast.joblib")
 
 
 
8
  PORT = int(os.getenv("PORT", "5000"))
9
 
 
10
  print(f"==> [BOOT] MODEL_PATH={MODEL_PATH}", flush=True)
11
 
12
  def load_pipeline(path: str):
13
- t0 = time.time()
14
  if not os.path.exists(path):
15
  raise FileNotFoundError(f"Model file not found: {path}")
16
  print(f"==> [LOAD] Loading model from {path} ...", flush=True)
17
- bundle = joblib.load(path)
18
- if isinstance(bundle, dict) and "pipeline" in bundle:
19
- pipe = bundle["pipeline"]
20
  print("==> [LOAD] Loaded dict bundle with 'pipeline'", flush=True)
21
  else:
22
- pipe = bundle
23
  print("==> [LOAD] Loaded pipeline object", flush=True)
24
- print(f"==> [LOAD] Done in {time.time()-t0:.2f}s", flush=True)
25
  return pipe
26
 
27
  try:
28
  pipe = load_pipeline(MODEL_PATH)
29
- MODEL_READY = True
30
- LOAD_ERROR = None
31
  except Exception as e:
32
- print("==> [ERROR] Model load failed:", e, file=sys.stderr, flush=True)
33
- pipe = None
34
- MODEL_READY = False
35
- LOAD_ERROR = str(e)
36
 
 
 
 
37
  @app.after_request
38
- def cors(resp):
39
  resp.headers["Access-Control-Allow-Origin"] = "*"
40
  resp.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
41
  resp.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
42
  return resp
43
 
 
 
 
44
  @app.get("/")
45
  def root():
46
- return jsonify({"service": "SuperKart API", "health": "/health", "predict": "/predict", "model_path": MODEL_PATH})
 
 
 
 
 
47
 
48
  @app.get("/health")
49
  def health():
50
- return (jsonify({"status": "ok", "model_path": MODEL_PATH}), 200) if MODEL_READY \
51
- else (jsonify({"status": "error", "model_path": MODEL_PATH, "error": LOAD_ERROR}), 500)
 
52
 
 
 
 
53
  @app.route("/predict", methods=["OPTIONS"])
54
  def predict_options():
55
  return make_response(("", 204))
@@ -58,17 +73,26 @@ def predict_options():
58
  def predict():
59
  if not MODEL_READY or pipe is None:
60
  return jsonify({"error": "Model not loaded", "details": LOAD_ERROR}), 503
61
- data = request.get_json(force=True)
62
- if isinstance(data, dict):
63
- df = pd.DataFrame([data])
64
- elif isinstance(data, list):
65
- df = pd.DataFrame(data)
66
- else:
67
- return jsonify({"error": "Payload must be an object or list of objects"}), 400
68
- preds = pipe.predict(df)
69
- preds = [float(x) if isinstance(x, (np.floating, float, int)) else x for x in preds]
70
- return jsonify({"predictions": preds})
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  if __name__ == "__main__":
73
- print("==> [RUN] Flask dev server starting on 0.0.0.0:5000", flush=True)
74
  app.run(host="0.0.0.0", port=PORT)
 
1
  from flask import Flask, request, jsonify, make_response
2
+ import joblib, pandas as pd, numpy as np, os, sys, time
3
 
 
4
  app = Flask(__name__)
5
 
6
+ # -----------------------------
7
+ # Config & Model Loading
8
+ # -----------------------------
9
+ MODEL_PATH = os.getenv("MODEL_PATH", "best_model_random_forest.joblib")
10
  PORT = int(os.getenv("PORT", "5000"))
11
 
12
+ print(f"==> [BOOT] Starting Flask app on port {PORT}")
13
  print(f"==> [BOOT] MODEL_PATH={MODEL_PATH}", flush=True)
14
 
15
  def load_pipeline(path: str):
16
+ start = time.time()
17
  if not os.path.exists(path):
18
  raise FileNotFoundError(f"Model file not found: {path}")
19
  print(f"==> [LOAD] Loading model from {path} ...", flush=True)
20
+ model_obj = joblib.load(path)
21
+ if isinstance(model_obj, dict) and "pipeline" in model_obj:
22
+ pipe = model_obj["pipeline"]
23
  print("==> [LOAD] Loaded dict bundle with 'pipeline'", flush=True)
24
  else:
25
+ pipe = model_obj
26
  print("==> [LOAD] Loaded pipeline object", flush=True)
27
+ print(f"==> [LOAD] Model load complete in {time.time()-start:.2f}s", flush=True)
28
  return pipe
29
 
30
  try:
31
  pipe = load_pipeline(MODEL_PATH)
32
+ MODEL_READY, LOAD_ERROR = True, None
 
33
  except Exception as e:
34
+ print(f"==> [ERROR] Model load failed: {e}", file=sys.stderr, flush=True)
35
+ pipe, MODEL_READY, LOAD_ERROR = None, False, str(e)
 
 
36
 
37
+ # -----------------------------
38
+ # Basic CORS (no external deps)
39
+ # -----------------------------
40
  @app.after_request
41
+ def add_cors_headers(resp):
42
  resp.headers["Access-Control-Allow-Origin"] = "*"
43
  resp.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
44
  resp.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
45
  return resp
46
 
47
+ # -----------------------------
48
+ # Health & Root
49
+ # -----------------------------
50
  @app.get("/")
51
  def root():
52
+ return jsonify({
53
+ "service": "SuperKart Sales Forecast API",
54
+ "health": "/health",
55
+ "predict": "/predict",
56
+ "model_path": MODEL_PATH
57
+ })
58
 
59
  @app.get("/health")
60
  def health():
61
+ if MODEL_READY:
62
+ return jsonify({"status": "ok", "model_path": MODEL_PATH}), 200
63
+ return jsonify({"status": "error", "error": LOAD_ERROR, "model_path": MODEL_PATH}), 500
64
 
65
+ # -----------------------------
66
+ # Prediction
67
+ # -----------------------------
68
  @app.route("/predict", methods=["OPTIONS"])
69
  def predict_options():
70
  return make_response(("", 204))
 
73
  def predict():
74
  if not MODEL_READY or pipe is None:
75
  return jsonify({"error": "Model not loaded", "details": LOAD_ERROR}), 503
 
 
 
 
 
 
 
 
 
 
76
 
77
+ try:
78
+ data = request.get_json(force=True)
79
+ if isinstance(data, dict):
80
+ df = pd.DataFrame([data])
81
+ elif isinstance(data, list):
82
+ df = pd.DataFrame(data)
83
+ else:
84
+ return jsonify({"error": "Invalid input. Must be JSON object or list of objects."}), 400
85
+
86
+ preds = pipe.predict(df)
87
+ preds = [float(p) if isinstance(p, (np.floating, float, int)) else p for p in preds]
88
+ return jsonify({"predictions": preds})
89
+
90
+ except Exception as e:
91
+ return jsonify({"error": "Prediction failed", "details": str(e)}), 500
92
+
93
+ # -----------------------------
94
+ # Entry Point
95
+ # -----------------------------
96
  if __name__ == "__main__":
97
+ print("==> [RUN] Flask dev server starting...", flush=True)
98
  app.run(host="0.0.0.0", port=PORT)