import joblib import pandas as pd import numpy as np from flask import Flask, request, jsonify # Initialize Flask app sales_revenue_api = Flask("SuperKart Outlet Sales Revenue Predictor") # Load the trained model, preprocessor, and outlier bounds model = joblib.load("./tuned_random_forest_model.pkl") preprocessor = joblib.load("./preprocessor_pipeline.pkl") outlier_bounds = joblib.load("./outlier_bounds.pkl") def preprocess_input(input_df): # Make a copy to avoid SettingWithCopyWarning processed_df = input_df.copy() # 1. Handle Product_Sugar_Content inconsistency processed_df['Product_Sugar_Content'] = processed_df['Product_Sugar_Content'].replace('reg', 'Regular') # 2. Create Store_Age feature current_year = 2025 processed_df['Store_Age'] = current_year - processed_df['Store_Establishment_Year'] # 3. Create Price_Per_Unit_Weight feature processed_df['Price_Per_Unit_Weight'] = processed_df['Product_MRP'] / processed_df['Product_Weight'] # 4. Apply Outlier Treatment (Capping/Flooring) using loaded bounds numerical_features_for_outliers = ['Product_Weight', 'Store_Age', 'Price_Per_Unit_Weight'] # these were the features used for outlier detection for col in numerical_features_for_outliers: if col in processed_df.columns and col in outlier_bounds: lower_bound, upper_bound = outlier_bounds[col] processed_df[col] = np.where(processed_df[col] < lower_bound, lower_bound, processed_df[col]) processed_df[col] = np.where(processed_df[col] > upper_bound, upper_bound, processed_df[col]) # 5. Drop unnecessary columns (the ones dropped in notebook preprocessing) columns_to_drop_final = ['Product_Id', 'Store_Id', 'Product_Allocated_Area', 'Store_Establishment_Year', 'Product_MRP'] processed_df = processed_df.drop(columns=columns_to_drop_final, errors='ignore') # The order of columns must match the X_train_new used during pipeline fitting # Re-order columns to match the training data feature order expected_feature_order = ['Product_Weight', 'Product_Sugar_Content', 'Product_Type', 'Store_Size', 'Store_Location_City_Type', 'Store_Type', 'Store_Age', 'Price_Per_Unit_Weight'] processed_df = processed_df[expected_feature_order] # 6. Apply the preprocessor (scaling and one-hot encoding) processed_data = preprocessor.transform(processed_df) return processed_data # Define a route for the home page @sales_revenue_api.get('/') def home(): return "Welcome to the SuperKart Outlet Sales Revenue Prediction API!" # Define an endpoint to predict price for a single house @sales_revenue_api.post('/v1/outlet') def predict_outlet_salesRevenue(): # Get JSON data from the request outlet_data = request.get_json() # Ensure all original required fields are present to reconstruct features required_fields = [ 'Product_Id', 'Product_Weight', 'Product_Sugar_Content', 'Product_Allocated_Area', 'Product_Type', 'Product_MRP', 'Store_Id', 'Store_Establishment_Year', 'Store_Size', 'Store_Location_City_Type', 'Store_Type' ] for field in required_fields: if field not in outlet_data: return jsonify({'error': f'Missing field: {field}'}), 400 # Convert the extracted data into a DataFrame input_df_raw = pd.DataFrame([outlet_data]) # Preprocess the input data processed_input = preprocess_input(input_df_raw) # Make a prediction using the trained model prediction = model.predict(processed_input).tolist()[0] # Return the prediction as a JSON response return jsonify({'Predicted_Product_Store_Sales_Total': prediction}) # Define an endpoint to predict price for a batch of houses @sales_revenue_api.post('/v1/outletbatch') def predict_outlet_salesRevenue_batch(): # Get the uploaded CSV file from the request file = request.files['file'] # Read the file into a DataFrame input_df_raw = pd.read_csv(file) # Preprocess the input data processed_input = preprocess_input(input_df_raw) # Make predictions for the batch data predictions = model.predict(processed_input).tolist() # Add predictions to the DataFrame input_df_raw['Predicted_Product_Store_Sales_Total'] = predictions # Convert results to dictionary result = input_df_raw.to_dict(orient="records") return jsonify(result) # Run the Flask app in debug mode if __name__ == '__main__': sales_revenue_api.run(debug=True)