Spaces:
Sleeping
Sleeping
| from flask import Flask, request, jsonify | |
| import pandas as pd | |
| import joblib | |
| import numpy as np | |
| import logging | |
| import json | |
| # Configure logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| # Initialize Flask app | |
| app = Flask(__name__) | |
| # Load the trained model | |
| try: | |
| model = joblib.load("best_sales_forecasting_model.pkl") | |
| logger.info("Model loaded successfully") | |
| except Exception as e: | |
| logger.error(f"Error loading model: {str(e)}") | |
| model = None | |
| def home(): | |
| """Health check endpoint""" | |
| return jsonify({ | |
| "message": "SuperKart Sales Forecasting API is running!", | |
| "status": "healthy", | |
| "model_loaded": model is not None | |
| }) | |
| def predict(): | |
| """Predict sales revenue endpoint""" | |
| try: | |
| # Get JSON data from request | |
| data = request.get_json() | |
| if not data: | |
| return jsonify({"error": "No data provided"}), 400 | |
| if model is None: | |
| return jsonify({"error": "Model not loaded"}), 500 | |
| # Validate required fields | |
| required_fields = [ | |
| 'Product_Weight', | |
| 'Product_Sugar_Content', | |
| 'Product_Allocated_Area', | |
| 'Product_Type', | |
| 'Product_MRP', | |
| 'Store_Establishment_Year', | |
| 'Store_Size', | |
| 'Store_Location_City_Type', | |
| 'Store_Type' | |
| ] | |
| missing_fields = [field for field in required_fields if field not in data] | |
| if missing_fields: | |
| return jsonify({ | |
| "error": "Missing required fields", | |
| "missing_fields": missing_fields | |
| }), 400 | |
| # Create DataFrame for prediction | |
| input_data = pd.DataFrame([{ | |
| 'Product_Weight': float(data['Product_Weight']), | |
| 'Product_Sugar_Content': str(data['Product_Sugar_Content']), | |
| 'Product_Allocated_Area': float(data['Product_Allocated_Area']), | |
| 'Product_Type': str(data['Product_Type']), | |
| 'Product_MRP': float(data['Product_MRP']), | |
| 'Store_Establishment_Year': int(data['Store_Establishment_Year']), | |
| 'Store_Size': str(data['Store_Size']), | |
| 'Store_Location_City_Type': str(data['Store_Location_City_Type']), | |
| 'Store_Type': str(data['Store_Type']) | |
| }]) | |
| # Make prediction | |
| prediction = model.predict(input_data)[0] | |
| # Prepare response | |
| response = { | |
| "prediction": float(prediction), | |
| "formatted_prediction": f"₹ {prediction:,.2f}", | |
| "input_data": data, | |
| "status": "success" | |
| } | |
| logger.info(f"Prediction made: {prediction}") | |
| return jsonify(response) | |
| except ValueError as e: | |
| logger.error(f"Validation error: {str(e)}") | |
| return jsonify({"error": f"Invalid data format: {str(e)}"}), 400 | |
| except Exception as e: | |
| logger.error(f"Prediction error: {str(e)}") | |
| return jsonify({"error": f"Prediction failed: {str(e)}"}), 500 | |
| def model_info(): | |
| """Get model information""" | |
| try: | |
| if model is None: | |
| return jsonify({"error": "Model not loaded"}), 500 | |
| # Get model type | |
| model_type = str(type(model)).split('.')[-1].replace("'>", "") | |
| return jsonify({ | |
| "model_type": model_type, | |
| "model_loaded": True, | |
| "supported_features": [ | |
| 'Product_Weight', | |
| 'Product_Sugar_Content', | |
| 'Product_Allocated_Area', | |
| 'Product_Type', | |
| 'Product_MRP', | |
| 'Store_Establishment_Year', | |
| 'Store_Size', | |
| 'Store_Location_City_Type', | |
| 'Store_Type' | |
| ], | |
| "prediction_type": "Sales Revenue Forecasting" | |
| }) | |
| except Exception as e: | |
| logger.error(f"Model info error: {str(e)}") | |
| return jsonify({"error": str(e)}), 500 | |
| def batch_predict(): | |
| """Batch prediction endpoint""" | |
| try: | |
| data = request.get_json() | |
| if not data or 'predictions' not in data: | |
| return jsonify({"error": "No batch data provided"}), 400 | |
| if model is None: | |
| return jsonify({"error": "Model not loaded"}), 500 | |
| predictions = [] | |
| errors = [] | |
| for i, item in enumerate(data['predictions']): | |
| try: | |
| # Calculate derived features | |
| current_year = 2025 | |
| price_efficiency = float(item['Product_MRP']) * 0.1 | |
| # Create DataFrame for prediction | |
| input_data = pd.DataFrame([{ | |
| 'Product_Weight': float(item['Product_Weight']), | |
| 'Product_Sugar_Content': str(item['Product_Sugar_Content']), | |
| 'Product_Allocated_Area': float(item['Product_Allocated_Area']), | |
| 'Product_Type': str(item['Product_Type']), | |
| 'Product_MRP': float(item['Product_MRP']), | |
| 'Store_Size': str(item['Store_Size']), | |
| 'Store_Location_City_Type': str(item['Store_Location_City_Type']), | |
| 'Store_Type': str(item['Store_Type']), | |
| 'Price_Efficiency': price_efficiency | |
| }]) | |
| prediction = model.predict(input_data)[0] | |
| predictions.append({ | |
| "index": i, | |
| "prediction": float(prediction), | |
| "formatted_prediction": f"₹ {prediction:,.2f}" | |
| }) | |
| except Exception as e: | |
| errors.append({ | |
| "index": i, | |
| "error": str(e) | |
| }) | |
| return jsonify({ | |
| "predictions": predictions, | |
| "errors": errors, | |
| "total_processed": len(data['predictions']), | |
| "successful_predictions": len(predictions), | |
| "failed_predictions": len(errors) | |
| }) | |
| except Exception as e: | |
| logger.error(f"Batch prediction error: {str(e)}") | |
| return jsonify({"error": str(e)}), 500 | |
| if __name__ == '__main__': | |
| app.run(host='0.0.0.0', port=7860, debug=False) | |