mdsalmon159 commited on
Commit
d87bf7f
·
verified ·
1 Parent(s): deb1255

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +85 -87
app.py CHANGED
@@ -1,110 +1,108 @@
1
 
2
- cat > app.py <<'PY'
3
- import os
4
- import logging
5
- import joblib
6
  import numpy as np
7
  import pandas as pd
 
8
  from flask import Flask, request, jsonify
9
 
10
- # optional CORS
11
- try:
12
- from flask_cors import CORS
13
- _CORS = True
14
- except Exception:
15
- _CORS = False
16
-
17
- # WSGI callable must be named `app`
18
- app = Flask(__name__)
19
- if _CORS:
20
- CORS(app)
21
-
22
- logging.basicConfig(level=logging.INFO)
23
- logger = logging.getLogger(__name__)
24
-
25
- MODEL_PATH = os.environ.get("MODEL_PATH", "superkart_prediction.joblib")
26
- model = None
27
- load_error = None
28
- if os.path.exists(MODEL_PATH):
29
- try:
30
- model = joblib.load(MODEL_PATH)
31
- logger.info(f"Loaded model from {MODEL_PATH}")
32
- except Exception as e:
33
- load_error = str(e)
34
- logger.exception("Failed to load model")
35
- else:
36
- load_error = f"Model file not found at {MODEL_PATH}"
37
- logger.warning(load_error)
38
 
 
 
39
 
40
- @app.route("/", methods=["GET"])
 
 
41
  def home():
42
- return jsonify({"message": "API up"}), 200
 
43
 
 
 
 
 
 
 
 
44
 
45
- @app.route("/v1/sales", methods=["POST"])
46
- def predict_single():
47
- if model is None:
48
- return jsonify({"error": "Model not loaded", "details": load_error}), 500
49
  try:
50
- data = request.get_json(force=True)
51
- expected_cols = [
52
- "Product_Id","Product_Weight","Product_Sugar_Content","Product_Allocated_Area",
53
- "Product_Type","Product_MRP","Store_Id","Store_Establishment_Year",
54
- "Store_Size","Store_Location_City_Type","Store_Type"
55
- ]
56
- row = {c: data.get(c, None) for c in expected_cols}
57
- df = pd.DataFrame([row])
58
- pred = model.predict(df)
59
- log_out = bool(data.get("log_output", False))
60
- val = float(np.exp(pred[0])) if log_out else float(pred[0])
61
- return jsonify({"predicted_sales": round(val, 2)}), 200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  except Exception as e:
63
- logger.exception("predict_single failed")
64
- return jsonify({"error": "prediction failed", "details": str(e)}), 500
65
 
 
 
 
 
 
 
 
66
 
67
- @app.route("/v1/sales/batch", methods=["POST"])
68
- def predict_batch():
69
- if model is None:
70
- return jsonify({"error": "Model not loaded", "details": load_error}), 500
71
  try:
72
- if "file" in request.files:
73
- df = pd.read_csv(request.files["file"])
74
- else:
75
- jb = request.get_json(force=True)
76
- if isinstance(jb, dict) and "data" in jb:
77
- df = pd.DataFrame(jb["data"])
78
- elif isinstance(jb, list):
79
- df = pd.DataFrame(jb)
80
- else:
81
- return jsonify({"error": "No file or JSON data provided"}), 400
82
-
83
- if df.empty:
84
- return jsonify({"error": "Input empty"}), 400
85
-
86
- preds = model.predict(df).tolist()
87
- log_flag = request.args.get("log_output", "false").lower() == "true"
88
- if log_flag:
89
- preds = [round(float(np.exp(p)), 2) for p in preds]
90
- else:
91
- preds = [round(float(p), 2) for p in preds]
92
 
93
- id_col = next((c for c in ("id", "ID", "Product_Id") if c in df.columns), None)
94
  if id_col:
95
- keys = df[id_col].astype(str).tolist()
96
- out = dict(zip(keys, preds))
97
  else:
98
- out = {str(i): preds[i] for i in range(len(preds))}
 
 
 
99
 
100
- return jsonify({"predictions": out}), 200
101
  except Exception as e:
102
- logger.exception("predict_batch failed")
103
- return jsonify({"error": "batch prediction failed", "details": str(e)}), 500
104
 
 
 
 
105
 
106
  if __name__ == "__main__":
107
- port = int(os.environ.get("PORT", 7860))
108
- logger.info("Starting local Flask server on port %s", port)
109
- app.run(host="0.0.0.0", port=port, debug=True)
110
- PY
 
1
 
 
 
 
 
2
  import numpy as np
3
  import pandas as pd
4
+ import joblib
5
  from flask import Flask, request, jsonify
6
 
7
+ # initiate flask application
8
+ sales_price_prediction_api = Flask("SuperKart Sales Price Prediction API")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ # Load the trained model
11
+ model = joblib.load("superkart_prediction.joblib")
12
 
13
+
14
+ # -------------------- HOME ROUTE --------------------
15
+ @sales_price_prediction_api.get("/")
16
  def home():
17
+ return "Welcome to the SuperKart Sales Prediction API!"
18
+
19
 
20
+ # -------------------- SINGLE SALES PREDICTION --------------------
21
+ @sales_price_prediction_api.post("/v1/sales")
22
+ def predict_sales_single():
23
+ """
24
+ Handles POST requests to predict sales for a single product.
25
+ Expects JSON input with required features.
26
+ """
27
 
 
 
 
 
28
  try:
29
+ sales_data = request.get_json()
30
+
31
+ # Extract features
32
+ sample = {
33
+ 'Product_Id': sales_data.get('Product_Id'),
34
+ 'Product_Weight': sales_data.get('Product_Weight'),
35
+ 'Product_Sugar_Content': sales_data.get('Product_Sugar_Content'),
36
+ 'Product_Allocated_Area': sales_data.get('Product_Allocated_Area'),
37
+ 'Product_Type': sales_data.get('Product_Type'),
38
+ 'Product_MRP': sales_data.get('Product_MRP'),
39
+ 'Store_Id': sales_data.get('Store_Id'),
40
+ 'Store_Establishment_Year': sales_data.get('Store_Establishment_Year'),
41
+ 'Store_Size': sales_data.get('Store_Size'),
42
+ 'Store_Location_City_Type': sales_data.get('Store_Location_City_Type'),
43
+ 'Store_Type': sales_data.get('Store_Type')
44
+ }
45
+
46
+ # Convert into DataFrame
47
+ input_df = pd.DataFrame([sample])
48
+
49
+ # Predict log-sales
50
+ log_pred = model.predict(input_df)[0]
51
+
52
+ # Convert log prediction to actual sales
53
+ predicted_sale = round(float(np.exp(log_pred)), 2)
54
+
55
+ return jsonify({"predicted_sales_in_dollars": predicted_sale})
56
+
57
  except Exception as e:
58
+ return jsonify({"error": str(e)}), 400
59
+
60
 
61
+ # -------------------- BATCH SALES PREDICTION --------------------
62
+ @sales_price_prediction_api.post("/v1/sales/batch")
63
+ def predict_sales_batch():
64
+ """
65
+ Handles batch prediction using uploaded CSV.
66
+ Returns a dict of ID → predicted_sales.
67
+ """
68
 
 
 
 
 
69
  try:
70
+ # Get uploaded CSV file
71
+ file = request.files.get("file")
72
+ if file is None:
73
+ return jsonify({"error": "No CSV file uploaded under key 'file'"}), 400
74
+
75
+ df = pd.read_csv(file)
76
+
77
+ # Predict log-sales
78
+ log_preds = model.predict(df).tolist()
79
+
80
+ # Convert log values to sales
81
+ predictions = [round(float(np.exp(p)), 2) for p in log_preds]
82
+
83
+ # Determine ID column
84
+ id_col = None
85
+ for col in ["id", "ID", "Product_Id"]:
86
+ if col in df.columns:
87
+ id_col = col
88
+ break
 
89
 
 
90
  if id_col:
91
+ ids = df[id_col].astype(str).tolist()
92
+ result = dict(zip(ids, predictions))
93
  else:
94
+ # fallback to index-based prediction
95
+ result = {str(i): predictions[i] for i in range(len(predictions))}
96
+
97
+ return jsonify({"predictions": result})
98
 
 
99
  except Exception as e:
100
+ return jsonify({"error": str(e)}), 400
101
+
102
 
103
+ # -------------------- RUN APP LOCALLY --------------------
104
+ # Hugging Face uses gunicorn to run "app", so we expose the variable below:
105
+ app = sales_price_prediction_api
106
 
107
  if __name__ == "__main__":
108
+ sales_price_prediction_api.run(host="0.0.0.0", port=7860, debug=True)