File size: 12,174 Bytes
95a4688
 
 
 
 
4b0fd58
 
95a4688
4b0fd58
cafb3e2
95a4688
eb4c870
4b0fd58
95a4688
 
 
 
 
 
4b0fd58
 
95a4688
 
4b0fd58
 
 
 
95a4688
4b0fd58
 
95a4688
 
4b0fd58
eb4c870
4b0fd58
 
 
 
95a4688
 
 
 
 
 
4b0fd58
 
95a4688
 
eb4c870
 
 
 
 
 
 
 
 
95a4688
eb4c870
95a4688
 
 
 
 
 
4b0fd58
 
95a4688
 
 
 
 
 
4b0fd58
 
95a4688
 
 
 
 
 
4b0fd58
 
95a4688
4b0fd58
 
95a4688
 
4b0fd58
 
 
 
 
 
eb4c870
95a4688
 
 
 
 
4b0fd58
 
95a4688
 
 
 
 
 
4b0fd58
 
95a4688
 
 
 
 
 
4b0fd58
 
95a4688
4b0fd58
 
95a4688
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import os                                                                       # Imports the 'os' module, which provides a way of using operating system dependent functionality
import joblib                                                                   # Imports the 'joblib' library, used for efficient serialization and deserialization of Python objects
from flask import Flask, request, jsonify                                       # Imports specific classes from the 'flask' framework
import pandas as pd                                                             # Imports the 'pandas' library, providing data structures and data analysis tools
import logging                                                                  # Imports the 'logging' module, used for logging events that occur during the execution of the program

# Initialize flask app with a name
sales_prediction = Flask(__name__)                                              # Creates an instance of the Flask class

# Configure logging
logging.basicConfig(level=logging.DEBUG)                                        # Configures the logging system to record all events at DEBUG level and above

# Load the trained model pipeline
try:                                                                            # Tries to load the model from a file
    model = joblib.load("SuperKart_best_Model.joblib")                          # # Attempts to load the pre-trained machine learning model pipeline                                      
    logging.info("Model loaded successfully.")                                  # Logs an informational message indicating that the model was loaded without errors
except Exception as e:                                                          # If an error occurs during the loading process
    logging.error(f"Error loading model: {e}")                                  # Logs an error message containing the specific error that occurred
    raise                                                                       # Raises the exception to propagate it to the caller

# Define an endpoint for making predictions
@sales_prediction.get('/')                                                      # Decorator that registers the home() function to handle GET requests                                                                                                                                
def home():                                                                     # Function that handles GET requests to the root URL ('/') of the API
    """
    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)
@sales_prediction.post('/v1/predict')                                           # Decorator that registers the predict_sales() function to handle POST requests to the '/v1/predict' endpoint
def predict_sales():                                                            # Function that handles POST requests to the '/v1/predict' endpoint
    """
    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:                                                                        # Tries to decode the JSON data from the request body
        business_data = request.get_json()                                      # Attempts to retrieve the JSON data sent in the body of the POST request
        logging.debug(f"Received data: {business_data}")                        # Logs the received data at the DEBUG level
    except Exception as e:                                                      # Catches any exception that occurs during JSON decoding                                                      
        logging.error(f"Error decoding JSON: {e}")                              # Logs an error message containing the specific JSON decoding error
        return jsonify({'error': f'Invalid JSON: {e}'}), 400                    # Returns a JSON response with an error message and a 400 Bad Request status code

    # Extract relevant features from the JSON data
    try:                                                                        # Tries to decode the JSON data from the request body                            
        business_data_sample = {                                                # Creates a dictionary containing the features required for prediction, extracted from the received JSON data
            'Product_Weight': business_data['Product_Weight'],
            'Product_Sugar_Content': business_data['Product_Sugar_Content'],
            'Product_Type': business_data['Product_Type'],
            'Product_Allocated_Area': business_data['Product_Allocated_Area'],
            'Product_MRP': business_data['Product_MRP'],
            'Store_Size': business_data['Store_Size'],
            'Store_Id': business_data['Store_Id'],
            'Store_Location_City_Type': business_data['Store_Location_City_Type'],
            'Store_Type': business_data['Store_Type'],
            'Store_Current_Age': business_data['Store_Current_Age']  
        }
    except KeyError as e:                                                       # Catches a KeyError if a required key is missing from the input JSON data  
        logging.error(f"Missing key in JSON data: {e}")                         # Logs an error message containing the specific JSON decoding error                                                        
        return jsonify({'error': f'Missing key: {e}'}), 400                     # Returns a JSON response with an error message and a 400 Bad Request status code
    except TypeError as e:                                                      # Catches a TypeError if the data type of a value in the JSON data is incorrect
        logging.error(f"Error with data types: {e}")                            # Logs an error message containing the specific JSON decoding error
        return jsonify({'error': f'Incorrect data type: {e}'}), 400             # Returns a JSON response with an error message and a 400 Bad Request status code                

    # Convert the extracted data into a Pandas DataFrame
    try:                                                                        # Tries to decode the JSON data from the request body   
        business_df = pd.DataFrame(business_data_sample, index=[0])             # Creates a Pandas DataFrame from the extracted feature dictionary, with a single row
        logging.debug(f"DataFrame: {business_df.head().to_string()}")           # Logs the first few rows of the DataFrame as a string
    except Exception as e:                                                      # Catches any exception that occurs during DataFrame creation
        logging.error(f"Error creating DataFrame: {e}")                         # Logs an error message containing the DataFrame creation error                                      
        return jsonify({'error': f'Error creating DataFrame: {e}'}), 500        # Returns a JSON response with an error message and a 500 Internal Server Error status code

    # Make predictions using the loaded model
    try:                                                                        # Tries to make predictions using the loaded model
        prediction = model.predict(business_df)                                 # Uses the loaded machine learning model to predict the sales for the input data in the DataFrame
        logging.debug(f"Prediction: {prediction}")                              # Logs the prediction result
    except Exception as e:                                                      # Catches any exception that occurs during the prediction process
        logging.error(f"Error during prediction: {e}")                          # Logs an error message containing the specific prediction error
        return jsonify({'error': f'Prediction error: {e}'}), 500                # Returns a JSON response with an error message and a 500 Internal Server Error status code

    # Return the prediction as a JSON response
    return jsonify({'prediction': list(prediction)})                            # Returns the prediction as a JSON object
    
# Define an endpoint for batch prediction (POST request)
@sales_prediction.post('/v1/batch_predict')                                     # Decorator that registers the batch_predict() function to handle POST requests to the '/v1/batch_predict' endpoint
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']                                            # Attempts to retrieve the uploaded file from the request
        logging.debug(f"Received file: {file.filename}")                        # Logs the filename of the uploaded file
    except Exception as e:                                                      # Catches any exception that occurs while getting the file
        logging.error(f"Error getting file: {e}")                               # Logs an error message containing the file retrieval error
        return jsonify({'error': f'Error getting file: {e}'}), 400              # Returns a JSON response with an error message and a 400 Bad Request status code

    # Read the CSV file into a Pandas DataFrame
    try:                                                                        # Tries to read the CSV file into a Pandas DataFrame
        df = pd.read_csv(file)                                                  # Reads the uploaded CSV file into a Pandas DataFrame                                                      
        logging.debug(f"DataFrame shape: {df.shape}")                           # Logs the shape of the DataFrame
    except Exception as e:                                                      # Catches any exception that occurs during CSV reading
        logging.error(f"Error reading CSV: {e}")                                # Logs an error message containing the CSV reading error
        return jsonify({'error': f'Error reading CSV file: {e}'}), 400          # Returns a JSON response with an error message and a 400 Bad Request status code

    # Make preductions using the loaded model
    try:                                                                        # Tries to make predictions using the loaded model
        prediction = model.predict(df)                                          # Uses the loaded machine learning model to predict sales for the data in the DataFrame
        logging.debug(f"Prediction: {prediction}")                              # Logs the prediction result
    except Exception as e:                                                      # Catches any exception that occurs during the prediction process
        logging.error(f"Error during prediction: {e}")                          # Logs an error message containing the prediction error
        return jsonify({'error': f'Prediction error: {e}'}), 500                # Returns a JSON response with an error message and a 500 Internal Server Error status code

    # Return the prediction as a JSON response
    return jsonify({'prediction': list(prediction)})                            # Returns the prediction as a JSON object                            

# Run the Flask app if this script is executed
if __name__ == '__main__':                                                      
    sales_prediction.run(debug=True)                                            # Starts the Flask development server if the script is run directly with debug mode enabled