Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files
app.py
CHANGED
|
@@ -10,15 +10,13 @@ import os
|
|
| 10 |
|
| 11 |
# --- Configuration ---
|
| 12 |
MODEL_PATH = "final_xgboost_pipeline.pkl"
|
| 13 |
-
APP_NAME = "SuperKart Sales Predictor"
|
| 14 |
|
| 15 |
# --- Initialize Flask App ---
|
| 16 |
app = Flask("SuperKart Sales Predictor")
|
| 17 |
|
| 18 |
# --- Global Model Loading ---
|
| 19 |
try:
|
| 20 |
-
|
| 21 |
-
model = MODEL_PATH
|
| 22 |
print("Model loaded successfully.") # Add logging
|
| 23 |
except Exception as e:
|
| 24 |
print(f"Error loading model: {e}") # Log error
|
|
@@ -33,12 +31,12 @@ def health_check():
|
|
| 33 |
print("Home route accessed.") # Add logging
|
| 34 |
return jsonify({
|
| 35 |
"status": "OK",
|
| 36 |
-
"service": APP_NAME,
|
| 37 |
"model_location": MODEL_PATH,
|
| 38 |
"model_status": "Loaded" if model else "Error: See logs",
|
| 39 |
"api_version": "No Versioning"
|
| 40 |
})
|
| 41 |
|
|
|
|
| 42 |
@app.route("/predict", methods=['POST']) # The simple, unversioned route
|
| 43 |
def predict_sales():
|
| 44 |
"""
|
|
@@ -50,21 +48,25 @@ def predict_sales():
|
|
| 50 |
return jsonify({'error': 'Prediction service unavailable. Model failed to load.'}), 503
|
| 51 |
|
| 52 |
try:
|
| 53 |
-
|
|
|
|
| 54 |
print(f"[{APP_NAME}] Received prediction request with data: {data}")
|
| 55 |
|
| 56 |
if not data:
|
| 57 |
-
return jsonify({'error': 'Invalid or empty JSON data provided.'}), 400
|
| 58 |
|
| 59 |
# --- Data Transformation ---
|
| 60 |
try:
|
| 61 |
# Create a one-row DataFrame
|
| 62 |
input_df = pd.DataFrame([data])
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
| 68 |
except KeyError as ke:
|
| 69 |
print(f"[{APP_NAME}] Missing required feature: {ke}")
|
| 70 |
return jsonify({'error': f'Missing required feature: {ke}. Please check all features are present.'}), 400
|
|
@@ -81,14 +83,15 @@ def predict_sales():
|
|
| 81 |
if isinstance(prediction, (np.float32, np.float64)):
|
| 82 |
predicted_sales = float(prediction)
|
| 83 |
else:
|
| 84 |
-
predicted_sales = prediction
|
| 85 |
|
| 86 |
print(f"[{APP_NAME}] Prediction result: {predicted_sales:.2f}")
|
| 87 |
|
| 88 |
# --- Response ---
|
|
|
|
| 89 |
return jsonify({
|
| 90 |
'status': 'success',
|
| 91 |
-
'
|
| 92 |
})
|
| 93 |
|
| 94 |
except Exception as e:
|
|
@@ -99,7 +102,7 @@ def predict_sales():
|
|
| 99 |
'error': 'Internal Server Error during prediction',
|
| 100 |
'details': str(e)
|
| 101 |
}), 500
|
| 102 |
-
|
| 103 |
|
| 104 |
# --- Local Runner (Optional: Comment out for production WSGI) ---
|
| 105 |
if __name__ == '__main__':
|
|
|
|
| 10 |
|
| 11 |
# --- Configuration ---
|
| 12 |
MODEL_PATH = "final_xgboost_pipeline.pkl"
|
|
|
|
| 13 |
|
| 14 |
# --- Initialize Flask App ---
|
| 15 |
app = Flask("SuperKart Sales Predictor")
|
| 16 |
|
| 17 |
# --- Global Model Loading ---
|
| 18 |
try:
|
| 19 |
+
model = joblib.load(MODEL_PATH)
|
|
|
|
| 20 |
print("Model loaded successfully.") # Add logging
|
| 21 |
except Exception as e:
|
| 22 |
print(f"Error loading model: {e}") # Log error
|
|
|
|
| 31 |
print("Home route accessed.") # Add logging
|
| 32 |
return jsonify({
|
| 33 |
"status": "OK",
|
|
|
|
| 34 |
"model_location": MODEL_PATH,
|
| 35 |
"model_status": "Loaded" if model else "Error: See logs",
|
| 36 |
"api_version": "No Versioning"
|
| 37 |
})
|
| 38 |
|
| 39 |
+
|
| 40 |
@app.route("/predict", methods=['POST']) # The simple, unversioned route
|
| 41 |
def predict_sales():
|
| 42 |
"""
|
|
|
|
| 48 |
return jsonify({'error': 'Prediction service unavailable. Model failed to load.'}), 503
|
| 49 |
|
| 50 |
try:
|
| 51 |
+
# 1. REMOVE force=True to enforce correct MIME type header
|
| 52 |
+
data = request.get_json()
|
| 53 |
print(f"[{APP_NAME}] Received prediction request with data: {data}")
|
| 54 |
|
| 55 |
if not data:
|
| 56 |
+
return jsonify({'error': 'Invalid or empty JSON data provided. Ensure Content-Type is application/json.'}), 400
|
| 57 |
|
| 58 |
# --- Data Transformation ---
|
| 59 |
try:
|
| 60 |
# Create a one-row DataFrame
|
| 61 |
input_df = pd.DataFrame([data])
|
| 62 |
+
|
| 63 |
+
# 2. REMOVE MANUAL TYPE CONVERSION
|
| 64 |
+
# A well-built ML pipeline should handle all feature transformations internally.
|
| 65 |
+
# input_df['Store_Establishment_Year'] = input_df['Store_Establishment_Year'].astype(str)
|
| 66 |
+
|
| 67 |
+
print(f"[{APP_NAME}] Input data prepared for pipeline.")
|
| 68 |
+
# output variable removed as it was only used for the previous error
|
| 69 |
+
|
| 70 |
except KeyError as ke:
|
| 71 |
print(f"[{APP_NAME}] Missing required feature: {ke}")
|
| 72 |
return jsonify({'error': f'Missing required feature: {ke}. Please check all features are present.'}), 400
|
|
|
|
| 83 |
if isinstance(prediction, (np.float32, np.float64)):
|
| 84 |
predicted_sales = float(prediction)
|
| 85 |
else:
|
| 86 |
+
predicted_sales = prediction # Should ideally be a float
|
| 87 |
|
| 88 |
print(f"[{APP_NAME}] Prediction result: {predicted_sales:.2f}")
|
| 89 |
|
| 90 |
# --- Response ---
|
| 91 |
+
# 3. FIX: Return the actual predicted value instead of the string message
|
| 92 |
return jsonify({
|
| 93 |
'status': 'success',
|
| 94 |
+
'predicted_sales': predicted_sales # Renamed key to 'predicted_sales' for clarity
|
| 95 |
})
|
| 96 |
|
| 97 |
except Exception as e:
|
|
|
|
| 102 |
'error': 'Internal Server Error during prediction',
|
| 103 |
'details': str(e)
|
| 104 |
}), 500
|
| 105 |
+
|
| 106 |
|
| 107 |
# --- Local Runner (Optional: Comment out for production WSGI) ---
|
| 108 |
if __name__ == '__main__':
|