import os # Provides access to operating system functionalities like reading files, interacting with directories, and managing environment variable import joblib # Used for saving and loading models efficiently. It allows serialization of Python objects, especially machine learning models. from flask import Flask, request, jsonify # Imports Flask framework for building a web API. Flask initializes the app, request handles incoming data, and jsonify converts responses to JSON format. import pandas as pd # Loads pandas, a powerful library for data analysis and manipulation, allowing structured data handling through DataFrames. import numpy as np # Imports numpy, which provides support for numerical computations, including arrays, mathematical functions, and statistical operations. import warnings # Enables control over Python warning messages that may arise due to deprecated features or ignored exceptions. import logging # Helps in tracking events and errors within the application by logging messages systematically. warnings.filterwarnings("ignore") # Suppresses warning messages to ensure cleaner output during execution. # Initialize flask app with a name sales_prediction = Flask(__name__) # Creates Flask application # Configure logging logging.basicConfig(level=logging.DEBUG) # Configures logging to display debug messages. # Load the trained model pipeline try: model = joblib.load("SuperKart_Sales_Prediction_Model.joblib") # Loads saved model logging.info("Model loaded successfully.") # Logs a success message except Exception as e: # To log any exception during handling logging.error(f"Error loading model: {e}") # Logs an error message if loading fails raise # Raises the error for troubleshooting. # Define an endpoint for making predictions # Returns a welcome message when accessed: @sales_prediction.get('/') def home(): """ This function handles GET requests to the root URL ('/') of the API. It returns a simple welcome message. """ return "Welcome to the SuperKart Sales Prediction App!" # Define an endpoint for single property prediction (POST request) # Handles single prediction requests and returns JSON response: @sales_prediction.post('/v1/predict') def predict_sales(): """ This function handles POST requests to the '/v1/predict' endpoint. It expects a JSON payload containing property details and returns the predicted rental price as a JSON response. """ # Get the JSON data from the request body try: business_data = request.get_json() # Extracts JSON data from request body logging.debug(f"Received data: {business_data}") # Logs the received data for debugging purposes except Exception as e: # To log any exception during handling logging.error(f"Error decoding JSON: {e}") # Logs an error if JSON decoding fails return jsonify({'error': f'Invalid JSON: {e}'}), 400 # Returns a JSON-formatted error response with a 400 (Bad Request) status code. This informs the client that there was an issue with their request. # Extract relevant features from the JSON data try: business_data_sample = { 'Product_Weight': business_data['Product_Weight'], # Extracts the weight of the product from the JSON data, which can be a crucial feature for predicting sales 'Product_Sugar_Content': business_data['Product_Sugar_Content'], # Retrieves the sugar content classification (e.g., low sugar, regular) of the product, which might influence customer preferences 'Product_Type': business_data['Product_Type'], # Identifies the broad category of the product, such as dairy, snacks, or frozen foods, helping in segmentation analysis. 'Product_Allocated_Area': business_data['Product_Allocated_Area'], # Captures the ratio of display space allocated to this product in a store, affecting visibility and sales performance 'Product_MRP': business_data['Product_MRP'], # Extracts the Maximum Retail Price of the product, a key factor influencing purchasing decisions. 'Store_Size': business_data['Store_Size'], # Retrieves the store's size classification (e.g., small, medium, large), which affects inventory and foot traffic. 'Store_Location_City_Type': business_data['Store_Location_City_Type'],# Identifies whether the store is in a Tier 1, Tier 2, or Tier 3 city, which impacts customer demographics and purchasing power 'Store_Type': business_data['Store_Type'], # Specifies the store format (e.g., supermarket, food mart, or departmental store), affecting pricing strategy and sales 'Store_Current_Age': business_data['Store_Current_Age'] # Calculates the store’s age based on its establishment year, potentially relevant for analyzing store performance over time. } except KeyError as e: logging.error(f"Missing key in JSON data: {e}") # Handles missing keys in JSON data return jsonify({'error': f'Missing key: {e}'}), 400 # Logs an error message and returns a JSON response with an HTTP 400 status code (Bad Request) except TypeError as e: # Handles TypeError, which occurs when the data received is in an unexpected format logging.error(f"Error with data types: {e}") # Logs an error message return jsonify({'error': f'Incorrect data type: {e}'}), 400 # Logs the issue and returns an error response with HTTP status 400. # Convert the extracted data into a Pandas DataFrame try: business_df = pd.DataFrame(business_data_sample, index=[0]) # Transforms the extracted business data sample into a single-row Pandas DataFrame for structured analysis and model predictions. logging.debug(f"DataFrame: {business_df.head().to_string()}") # Logs the first few rows of the DataFrame in a formatted string for clearer debugging output except Exception as e: # To log any exception during handling logging.error(f"Error creating DataFrame: {e}") # Logs an error message if DataFrame creation fails return jsonify({'error': f'Error creating DataFrame: {e}'}), 500 # Returns a JSON-formatted error message with a 500 Internal Server Error status, signaling a failure in DataFrame processing. # Make predictions using the loaded model try: prediction = model.predict(business_df) # Uses the loaded model to make predictions on the business data logging.debug(f"Prediction: {prediction}") # Logs an error message except Exception as e: # To log any exception during handling logging.error(f"Error during prediction: {e}") # Logs an error message if DataFrame creation fails return jsonify({'error': f'Prediction error: {e}'}), 500 # Returning an error code 500 if any issue with JSON # Return the prediction as a JSON response return jsonify({'prediction': list(prediction)}) # Returns the prediction as a JSON response # Define an endpoint for batch prediction (POST request) @sales_prediction.post('/v1/batch_predict') def batch_predict(): """ This function handles POST requests to the '/v1/batch_predict' endpoint. It expects a JSON payload containing a list of property details and returns the predicted rental prices for each property as a JSON response. """ # Get the uploaded CSV file from the request try: file = request.files['file'] # Retrieves the uploaded file from the request logging.debug(f"Received file: {file.filename}") # Logs the received file for debugging purposes except Exception as e: # To log any exception during handling logging.error(f"Error getting file: {e}") # Logs an error if file retrieval fails return jsonify({'error': f'Error getting file: {e}'}), 400 # Logs the issue and returns an error response with HTTP status 400. # Read the CSV file into a Pandas DataFrame try: df = pd.read_csv(file) # creating a variable to store the csv file logging.debug(f"DataFrame shape: {df.shape}") # Logs the shape of the DataFrame for debugging purposes except Exception as e: # To log any exception during handling logging.error(f"Error reading CSV: {e}") # Logs an error if CSV reading fails return jsonify({'error': f'Error reading CSV file: {e}'}), 400 # Logs the issue and returns an error response with HTTP status 400. # Make preductions using the loaded model try: prediction = model.predict(df) # Fit the model to variable 'prediction' logging.debug(f"Prediction: {prediction}") # Logs the prediction for debugging purposes except Exception as e: # To log any exception during handling logging.error(f"Error during prediction: {e}") # Logs an error if prediction fails return jsonify({'error': f'Prediction error: {e}'}), 500 # Returning an error code 500 if any issue with JSON # Return the prediction as a JSON response return jsonify({'prediction': list(prediction)}) # Returns the prediction as a JSON response # Run the Flask app if this script is executed if __name__ == '_main_': # Checks if the script is executed directly. sales_prediction.run(debug=True) # Display the sales predicted and handle any debug issue