mdsalmon159 commited on
Commit
6d4e93b
·
verified ·
1 Parent(s): 59e9ff9

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +139 -84
app.py CHANGED
@@ -1,94 +1,149 @@
1
-
2
  import numpy as np
3
  import pandas as pd
4
  import joblib
5
  from flask import Flask, request, jsonify
 
6
 
7
- #initate 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
- # Define a route for the home page (GET request)
15
- @SalesPredictionBackend_api.get('/')
16
  def home():
17
- """
18
- This function handles GET requests to the root URL ('/') of the API.
19
- It returns a simple welcome message.
20
- """
21
- return "Welcome to the SuperKart Sales Prediction API!"
22
-
23
- # Define an endpoint for single property prediction (POST request)
24
- @SalesPredictionBackend_api.post('/v1/sales')
25
- def predict_rental_prife():
26
- """
27
- This function handles POST requests to the '/v1/sales' endpoint.
28
- It expects a JSON payload containing producr details and returns
29
- the predicted sales amount as a JSON response.
30
- """
31
- # Get the JSON data from the request body
32
- sales_data = request.get_json()
33
-
34
- # Extract relevant features from the JSON data
35
- sample = {
36
- 'Product_Id': sales_data['Product_Id'],
37
- 'Product_Weight': sales_data['Product_Weight'],
38
- 'Product_Sugar_Content': sales_data['Product_Sugar_Content'],
39
- 'Product_Allocated_Area': sales_data['Product_Allocated_Area'],
40
- 'Product_Allocated_Area': sales_data['Product_Allocated_Area'],
41
- 'Product_Type': sales_data['Product_Type'],
42
- 'Product_MRP': sales_data['Product_MRP'],
43
- 'Store_Id': sales_data['Store_Id'],
44
- 'Store_Establishment_Year': sales_data['Store_Establishment_Year'],
45
- 'Store_Size': sales_data['Store_Size'],
46
- 'Store_Location_City_Type': sales_data['Store_Location_City_Type'],
47
- 'Store_Type': sales_data['Store_Type']
48
- }
49
- #Convert the extracted sata into a Panda Dataframe
50
- input_data = pd.DataFrame([sample])
51
-
52
- #Make prediction (get sales_prediction)
53
- prediction_log_sale = model.predict(input_data)
54
-
55
- #calculated_sale
56
- predicted_sale = np.exp(prediction_log_sale[0])
57
-
58
- #convert predicted price to Pyton float
59
- predicted_sale = round(float(predicted_sale), 2)
60
-
61
- #return the sales
62
- return jsonify({'predicted Sales (indollars)': predicted_sale})
63
-
64
- #define an endpoint for batch predictions (POST request)
65
- @SalesPredictionBackend_api.post('/v1/sales/batch')
 
 
 
 
 
 
 
 
 
 
 
 
66
  def predict_sales_batch():
67
- """
68
- This function handles POST requests to the '/v1/rentalbatch' endpoint.
69
- It expects a CSV file containing property details for multiple properties
70
- and returns the predicted rental prices as a dictionary in the JSON response.
71
- """
72
-
73
- # Get the uploaded CSV file from the requqst
74
- file = request. files['file']
75
-
76
- # Read the CSV file into a Pandas DataFrame
77
- input_data = pd.read_csv(file)
78
-
79
- # Make predictions for all properties in the DataFrame (get log_prices)
80
- predicted_log_sales = model.predict(input_data).tolist()
81
-
82
- #calculate actual prices
83
- predicted_prices = [round(float(np.exp(log_price)), 2) for log_price in predicted_log_prices]
84
-
85
- # Create a dictionary of predictions with property IDs as keys
86
- property_ids = input_data['id'].tolist() # Assuming 'id' is the property ID column
87
- output_dict = dict(zip(property_ids, predicted_prices) ) # Use actual prices
88
- # Return the predictions dictionary as
89
- return output_dict
90
-
91
- # Run the Flask application in debug mode if this script is executed directly
92
- if __name__ == '_main_':
93
- sales_price_prediction_api.run(debug=True)
94
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
  import numpy as np
3
  import pandas as pd
4
  import joblib
5
  from flask import Flask, request, jsonify
6
+ from flask_cors import CORS
7
 
8
+ # Create Flask app
9
+ app = Flask("SuperKart Sales Prediction API")
10
+ CORS(app) # allow cross-origin requests (useful for frontend calls)
11
 
12
+ # Load the trained model (adjust path if different)
13
+ MODEL_PATH = os.environ.get("MODEL_PATH", "superkart_prediction.joblib")
14
+ try:
15
+ model = joblib.load(MODEL_PATH)
16
+ except Exception as e:
17
+ # If model can't be loaded, keep model = None and return helpful errors later
18
+ model = None
19
+ load_error = str(e)
20
+ else:
21
+ load_error = None
22
 
23
 
24
+ @app.route("/", methods=["GET"])
 
25
  def home():
26
+ return "Welcome to the SuperKart Sales Prediction API!", 200
27
+
28
+
29
+ @app.route("/v1/sales", methods=["POST"])
30
+ def predict_sales_single():
31
+ """
32
+ Expects JSON body with the product/store features required by the model.
33
+ Example JSON:
34
+ {
35
+ "Product_Id": 123,
36
+ "Product_Weight": 1.23,
37
+ "Product_Sugar_Content": "Low",
38
+ "Product_Allocated_Area": 10,
39
+ "Product_Type": "TypeA",
40
+ "Product_MRP": 99.99,
41
+ "Store_Id": "S1",
42
+ "Store_Establishment_Year": 1998,
43
+ "Store_Size": "Small",
44
+ "Store_Location_City_Type": "Tier1",
45
+ "Store_Type": "Supermarket",
46
+ "log_output": true # optional: set true if model predicts log(sales)
47
+ }
48
+ """
49
+ if model is None:
50
+ return jsonify({"error": "Model not loaded", "details": load_error}), 500
51
+
52
+ try:
53
+ data = request.get_json()
54
+ if data is None:
55
+ return jsonify({"error": "Invalid or empty JSON body"}), 400
56
+
57
+ # Extract expected features - adapt these keys to your model's expected columns
58
+ expected_cols = [
59
+ "Product_Id", "Product_Weight", "Product_Sugar_Content", "Product_Allocated_Area",
60
+ "Product_Type", "Product_MRP", "Store_Id", "Store_Establishment_Year",
61
+ "Store_Size", "Store_Location_City_Type", "Store_Type"
62
+ ]
63
+
64
+ # Build dictionary with available keys, set missing keys to None
65
+ row = {col: data.get(col, None) for col in expected_cols}
66
+
67
+ # Convert to DataFrame
68
+ input_df = pd.DataFrame([row])
69
+
70
+ # Predict
71
+ pred = model.predict(input_df)
72
+ # Some models predict log-sales; allow caller to indicate or default to False
73
+ log_output = bool(data.get("log_output", False))
74
+ if log_output:
75
+ sale = float(np.exp(pred[0]))
76
+ else:
77
+ sale = float(pred[0])
78
+
79
+ sale = round(sale, 2)
80
+ return jsonify({"predicted_sales": sale}), 200
81
+
82
+ except Exception as e:
83
+ return jsonify({"error": "Prediction failed", "details": str(e)}), 500
84
+
85
+
86
+ @app.route("/v1/sales/batch", methods=["POST"])
87
  def predict_sales_batch():
88
+ """
89
+ Accepts a CSV file upload under the key 'file' (multipart/form-data) or JSON list under key 'data'.
90
+ Returns a JSON mapping of row index (or ID column if present) to predicted sales.
91
+ """
92
+ if model is None:
93
+ return jsonify({"error": "Model not loaded", "details": load_error}), 500
94
+
95
+ try:
96
+ # 1) CSV upload via form-data
97
+ if "file" in request.files:
98
+ file = request.files["file"]
99
+ df = pd.read_csv(file)
100
+ else:
101
+ # 2) JSON body with 'data' key: list of records
102
+ json_body = request.get_json()
103
+ if not json_body:
104
+ return jsonify({"error": "No file uploaded and no JSON body provided"}), 400
105
+ if "data" in json_body:
106
+ df = pd.DataFrame(json_body["data"])
107
+ else:
108
+ # maybe user sent a list directly
109
+ if isinstance(json_body, list):
110
+ df = pd.DataFrame(json_body)
111
+ else:
112
+ return jsonify({"error": "JSON must be a list of records or contain 'data' key"}), 400
113
+
114
+ if df.empty:
115
+ return jsonify({"error": "Input dataframe is empty"}), 400
116
+
117
+ # Keep track of an ID column if present to map predictions back
118
+ id_col = None
119
+ for candidate in ("id", "ID", "product_id", "Product_Id"):
120
+ if candidate in df.columns:
121
+ id_col = candidate
122
+ break
123
+
124
+ # Predict (model must accept the dataframe columns as-is)
125
+ preds = model.predict(df).tolist()
126
+
127
+ # Handle whether model output is in log-space or not.
128
+ # Optionally accept a query param `log_output=true`
129
+ log_output_flag = request.args.get("log_output", "false").lower() == "true"
130
+ if log_output_flag:
131
+ preds = [float(round(np.exp(p), 2)) for p in preds]
132
+ else:
133
+ preds = [float(round(p, 2)) for p in preds]
134
+
135
+ if id_col:
136
+ ids = df[id_col].astype(str).tolist()
137
+ out = dict(zip(ids, preds))
138
+ else:
139
+ out = {str(i): preds[i] for i in range(len(preds))}
140
+
141
+ return jsonify({"predictions": out}), 200
142
+
143
+ except Exception as e:
144
+ return jsonify({"error": "Batch prediction failed", "details": str(e)}), 500
145
+
146
+
147
+ if __name__ == "__main__":
148
+ # For local debugging only. In production (gunicorn) the app object must be importable as 'app'
149
+ app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 8080)), debug=True)