aibtus commited on
Commit
3670c7d
·
verified ·
1 Parent(s): 3b59c42

Upload folder using huggingface_hub

Browse files
Files changed (5) hide show
  1. Dockerfile +28 -0
  2. SuperKart.csv +0 -0
  3. app.py +71 -0
  4. requirements.txt +6 -0
  5. tuned_xgb_sales_forecaster.pkl +3 -0
Dockerfile ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dockerfile
2
+
3
+ # Use a specific Python base image for stability and size optimization
4
+ FROM python:3.12-slim
5
+
6
+ # Set the working directory inside the container
7
+ WORKDIR /app
8
+
9
+ # Copy the requirements file and install dependencies
10
+ # Use --no-cache-dir to keep the image size small
11
+ COPY requirements.txt .
12
+ RUN pip install --no-cache-dir -r requirements.txt
13
+
14
+ # Copy the Flask application and the serialized model
15
+ COPY app.py .
16
+ COPY tuned_xgb_sales_forecaster.pkl .
17
+
18
+ # Expose the port the Flask app will run on
19
+ EXPOSE 7860
20
+
21
+ # Command to Start the Application (Gunicorn)
22
+ # This is the crucial part, borrowing from your colleague's working model:
23
+ # - `-w 4`: 4 worker processes for concurrency
24
+ # - `-b 0.0.0.0:7860`: Binds to the required port and all interfaces
25
+ # - `app:app`: The application target. It means:
26
+ # - look in file 'app.py' (the first 'app')
27
+ # - for the Flask instance named 'app' (the second 'app')
28
+ CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:7860", "app:app"]
SuperKart.csv ADDED
The diff for this file is too large to render. See raw diff
 
app.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+
3
+ # Import necessary libraries
4
+ import joblib
5
+ import numpy as np
6
+ import pandas as pd
7
+ from flask import Flask, request, jsonify
8
+
9
+ # Initialize the Flask application
10
+ # Using __name__ is essential for Flask to correctly find its resources.
11
+ app = Flask(__name__)
12
+ app.name = "SuperKart Sales Forecaster" # Explicitly set the name property for logging
13
+
14
+ # Define the model filename
15
+ # NOTE: Ensure the path 'backend_files/tuned_xgb_sales_forecaster.pkl' is correct
16
+ # relative to where app.py is run.
17
+ MODEL_FILE = 'backend_files/tuned_xgb_sales_forecaster.pkl'
18
+
19
+ # Define the 10 feature columns expected by the model pipeline
20
+ FEATURE_COLS = [
21
+ 'Product_Weight', 'Product_Sugar_Content', 'Product_Allocated_Area',
22
+ 'Product_Type', 'Product_MRP', 'Store_Size',
23
+ 'Store_Location_City_Type', 'Store_Type', 'Store_Age',
24
+ 'Product_Category_Simplified'
25
+ ]
26
+
27
+ # --- Load the Model Pipeline (Global scope, loads once on startup) ---
28
+ try:
29
+ model_pipeline = joblib.load(MODEL_FILE)
30
+ print("Model loaded successfully.")
31
+ except Exception as e:
32
+ print(f"CRITICAL ERROR: Model not found at {MODEL_FILE}: {e}. Check Dockerfile.")
33
+ model_pipeline = None
34
+
35
+ @app.route('/predict', methods=['POST'])
36
+ def predict_sales():
37
+ if model_pipeline is None:
38
+ return jsonify({'error': 'Server setup error: Model not loaded.'}), 500
39
+
40
+ try:
41
+ # force=True is often necessary when content-type headers are not set perfectly
42
+ data = request.get_json(force=True)
43
+
44
+ # Ensure data is a list of dictionaries, even if we only send one
45
+ if not isinstance(data, list) or not data:
46
+ return jsonify({'error': 'Input data must be a non-empty list of prediction objects.'}), 400
47
+
48
+ # Ensure input data matches the feature columns
49
+ input_df = pd.DataFrame(data, columns=FEATURE_COLS)
50
+
51
+ # Prediction on log scale
52
+ log_prediction = model_pipeline.predict(input_df)
53
+
54
+ # Inverse transformation: sales = exp(y) - 1
55
+ prediction_original_scale = np.expm1(log_prediction)
56
+
57
+ response = {
58
+ 'status': 'success',
59
+ # We only expect one prediction, so take the first element [0]
60
+ 'predicted_sales_revenue': round(prediction_original_scale[0], 2)
61
+ }
62
+ return jsonify(response)
63
+
64
+ except Exception as e:
65
+ # Log the detailed exception on the server side for debugging
66
+ print(f"Prediction failed with exception: {e}")
67
+ return jsonify({'error': f'Prediction logic failed: {str(e)}'}), 400
68
+
69
+ if __name__ == '__main__':
70
+ # This runs the server inside the Docker container
71
+ app.run(host='0.0.0.0', port=5000)
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Flask==3.0.3
2
+ pandas==2.2.2
3
+ numpy==1.26.4
4
+ scikit-learn==1.6.1
5
+ joblib==1.4.2
6
+ xgboost==2.1.4
tuned_xgb_sales_forecaster.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64e94ad83c2cb59138fd0addc972f5484caad0c21455161edb6465fafe8f24ae
3
+ size 612275