Vaddiritz commited on
Commit
1c8e3bc
·
verified ·
1 Parent(s): 018c9c2

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. Dockerfile +2 -2
  2. app.py +102 -27
Dockerfile CHANGED
@@ -18,5 +18,5 @@ EXPOSE 7860
18
 
19
  # Start the Flask app using gunicorn
20
  # - app: refers to app.py
21
- # - rental_price_predictor_api: the Flask app object in app.py
22
- CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:7860", "app:rental_price_predictor_api"]
 
18
 
19
  # Start the Flask app using gunicorn
20
  # - app: refers to app.py
21
+ # - app: the Flask app object in app.py (corrected from rental_price_predictor_api)
22
+ CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:7860", "app:app"]
app.py CHANGED
@@ -1,45 +1,120 @@
1
 
2
  # Import necessary libraries
3
  import numpy as np
4
- import joblib
5
- import pandas as pd
6
- from flask import Flask, request, jsonify
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- # Initialize the Flask application
9
- superkart_salesprice_predictor_api = Flask("Super Kart Product Sales Price Predictor")
10
 
11
- # Load the trained machine learning model
12
- model = joblib.load(saved_model_path)
 
13
 
14
  # Define a route for the home page (GET request)
15
- @superkart_salesprice_predictor_api.get('/')
16
  def home():
17
  return "Welcome to the Super Kart Product Sales Price Prediction API!"
18
 
19
  # Endpoint for single property prediction
20
- @superkart_salesprice_predictor_api.post('/v1/salesprice')
21
  def predict_sales_price():
22
- property_data = request.get_json()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
- sample = {
25
- 'Product_Weight': property_data['Product_Weight'],
26
- 'Product_Sugar_Content': property_data['Product_Sugar_Content'],
27
- 'Product_Allocated_Area': property_data['Product_Allocated_Area'],
28
- 'Product_Type': property_data['Product_Type'],
29
- 'Product_MRP': property_data['Product_MRP'],
30
- 'Store_Size': property_data['Store_Size'],
31
- 'Store_Location_City_Type': property_data['Store_Location_City_Type'],
32
- 'Store_Type': property_data['Store_Type'],
33
- 'Store_Age': property_data['Store_Age']
34
- }
35
 
36
- input_data = pd.DataFrame([sample])
37
 
38
- predicted_sales_price = model.predict(input_data)[0]
39
- predicted_price = round(float(np.exp(predicted_sales_price)), 2)
 
 
 
 
40
 
41
- return jsonify({'Predicted Price': predicted_price})
42
 
43
- # Run the Flask application in debug mode if this script is executed directly
 
 
44
  if __name__ == '__main__':
45
- superkart_salesprice_predictor_api.run(debug=True)
 
 
 
1
 
2
  # Import necessary libraries
3
  import numpy as np
4
+ import joblib
5
+ import pandas as pd
6
+ from flask import Flask, request, jsonify
7
+ import traceback # Import traceback to print detailed error info
8
+
9
+ # Define the path where the model is saved
10
+ # NOTE: This path should be accessible within the Docker container.
11
+ # When you upload the deployment_files folder to the Space,
12
+ # the .joblib file will be at the root of the container's /app directory.
13
+ # Adjust the path accordingly. Assuming the model file is at the root of the
14
+ # uploaded directory within the container.
15
+ # If saved_model_path was defined as "/content/drive/MyDrive/...", that path
16
+ # is not valid inside the Docker container.
17
+ # Let's assume the model is in the same directory as app.py inside the container.
18
+ # The model file was saved as "SuperKart_v1_0.joblib" in
19
+ # "/content/drive/MyDrive/Colab Notebooks/ModelDeployment_SuperKart/deployment_files/"
20
+ # When uploading "deployment_files" to the space, the contents are placed in the root.
21
+ # So, the model file inside the container should be just the filename.
22
+ model_file_name = "SuperKart_v1_0.joblib"
23
+ try:
24
+ # Load the trained machine learning model
25
+ model = joblib.load(model_file_name)
26
+ print(f"Model loaded successfully from {model_file_name}")
27
+ except FileNotFoundError:
28
+ print(f"Error: Model file not found at {model_file_name}")
29
+ model = None # Set model to None if loading fails
30
+ except Exception as e:
31
+ print(f"Error loading model: {e}")
32
+ traceback.print_exc()
33
+ model = None # Set model to None if loading fails
34
 
 
 
35
 
36
+ # Initialize the Flask application
37
+ # Use the name 'app' which is convention for Gunicorn
38
+ app = Flask(__name__)
39
 
40
  # Define a route for the home page (GET request)
41
+ @app.route('/')
42
  def home():
43
  return "Welcome to the Super Kart Product Sales Price Prediction API!"
44
 
45
  # Endpoint for single property prediction
46
+ @app.route('/v1/salesprice', methods=['POST'])
47
  def predict_sales_price():
48
+ # Check if the model was loaded successfully
49
+ if model is None:
50
+ return jsonify({"error": "Model not loaded. Cannot make predictions."}), 500
51
+
52
+ try:
53
+ property_data = request.get_json(force=True) # force=True to handle requests without content-type set
54
+
55
+ # Validate incoming JSON data structure
56
+ expected_keys = [
57
+ 'Product_Weight', 'Product_Sugar_Content', 'Product_Allocated_Area',
58
+ 'Product_Type', 'Product_MRP', 'Store_Size',
59
+ 'Store_Location_City_Type', 'Store_Type', 'Store_Age'
60
+ ]
61
+ if not all(key in property_data for key in expected_keys):
62
+ missing_keys = [key for key in expected_keys if key not in property_data]
63
+ return jsonify({"error": f"Missing keys in input data: {missing_keys}"}), 400
64
+
65
+ # Create a sample dictionary with the expected keys and data types
66
+ sample = {
67
+ 'Product_Weight': property_data.get('Product_Weight'),
68
+ 'Product_Sugar_Content': property_data.get('Product_Sugar_Content'),
69
+ 'Product_Allocated_Area': property_data.get('Product_Allocated_Area'),
70
+ 'Product_Type': property_data.get('Product_Type'),
71
+ 'Product_MRP': property_data.get('Product_MRP'),
72
+ 'Store_Size': property_data.get('Store_Size'),
73
+ 'Store_Location_City_Type': property_data.get('Store_Location_City_Type'),
74
+ 'Store_Type': property_data.get('Store_Type'),
75
+ 'Store_Age': property_data.get('Store_Age')
76
+ }
77
+
78
+ # Convert to DataFrame
79
+ # It's crucial that the column names here match the features expected by your pipeline
80
+ # after the initial data processing (like dropping IDs and adding Store_Age).
81
+ # Also ensure the data types match. Your payload sends Store_Size and Store_Location_City_Type
82
+ # as "Medium" and "Tier 2", but your preprocessing maps these to numerical values (1, 2, 3).
83
+ # The frontend also sends 1, 2, 3. The backend should probably expect the mapped numerical values
84
+ # consistent with the trained model's expectation after preprocessing.
85
+ # Let's adjust the payload expectation to match the numerical mapping done during training.
86
+ # The payload should send 1, 2, or 3 for Store_Size and Store_Location_City_Type.
87
+ # If you want to send "Medium", "Tier 2" etc., you need to apply the mapping in the backend Flask app before prediction.
88
+
89
+ # Assuming the *input payload* for Store_Size and Store_Location_City_Type is already the mapped numerical value (1, 2, or 3)
90
+ # This aligns with the frontend Streamlit app code.
91
+ input_data = pd.DataFrame([sample])
92
+
93
+
94
+ # Perform prediction
95
+ predicted_sales_price = model.predict(input_data)
96
 
97
+ # Your original code applied np.exp to the prediction.
98
+ # This implies your model was trained on log-transformed target variable.
99
+ # Ensure this is consistent with how your model was trained.
100
+ # If your model predicts the original scale, remove np.exp.
101
+ # Assuming log transformation was used:
102
+ predicted_price = round(float(np.exp(predicted_sales_price[0])), 2) # prediction returns an array, take the first element
 
 
 
 
 
103
 
104
+ return jsonify({'Predicted Price': predicted_price}), 200 # Return 200 status code for success
105
 
106
+ except Exception as e:
107
+ # Log the error on the server side
108
+ print(f"An error occurred during prediction: {e}")
109
+ traceback.print_exc() # Print traceback to logs for detailed error info
110
+ # Return an error response to the client
111
+ return jsonify({"error": "An internal server error occurred during prediction.", "details": str(e)}), 500
112
 
 
113
 
114
+ # Run the Flask application using Gunicorn (as defined in Dockerfile CMD)
115
+ # The if __name__ == '__main__': block is not strictly necessary when using Gunicorn
116
+ # but can be useful for local testing.
117
  if __name__ == '__main__':
118
+ # For local testing, uncomment the line below and run this script directly
119
+ # superkart_salesprice_predictor_api.run(debug=True, host='0.0.0.0', port=7860)
120
+ pass # Do nothing when run by Gunicorn