diff --git a/app.py b/app.py index 4caae51..6ef4a9f 100644 --- a/app.py +++ b/app.py @@ -1,368 +1,133 @@ -from flask import Flask, request, render_template -from flask_cors import cross_origin -import sklearn +from flask import Flask, request, render_template, jsonify import pickle -import pandas as pd +import numpy as np +from datetime import datetime app = Flask(__name__) -model = pickle.load(open("flight_rf.pkl", "rb")) - - -@app.route("/") -@cross_origin() +# Load the trained Random Forest model +try: + with open('flight_rf.pkl', 'rb') as file: + model = pickle.load(file) + print("Model loaded successfully!") +except FileNotFoundError: + print("Error: flight_rf.pkl not found. Please ensure the model file is in the same directory.") + model = None +except Exception as e: + print(f"Error loading model: {str(e)}") + model = None + +# Define mappings for categorical variables +AIRLINE_MAPPING = { + 'Jet Airways': 0, 'IndiGo': 1, 'Air India': 2, 'Multiple carriers': 3, + 'SpiceJet': 4, 'Vistara': 5, 'Air Asia': 6, 'GoAir': 7, + 'Multiple carriers Premium economy': 8, 'Jet Airways Business': 9, + 'Vistara Premium economy': 10, 'Trujet': 11 +} + +SOURCE_MAPPING = {'Delhi': 0, 'Kolkata': 1, 'Mumbai': 2, 'Chennai': 3} + +DESTINATION_MAPPING = {'Cochin': 0, 'Delhi': 1, 'New Delhi': 2, 'Hyderabad': 3, 'Kolkata': 4} + +def extract_datetime_features(datetime_str): + """Extract features from datetime string""" + try: + dt = datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M') + return { + 'hour': dt.hour, 'day': dt.day, 'month': dt.month, 'year': dt.year, + 'weekday': dt.weekday(), 'is_weekend': 1 if dt.weekday() >= 5 else 0 + } + except: + return {'hour': 12, 'day': 15, 'month': 6, 'year': 2024, 'weekday': 0, 'is_weekend': 0} + +def calculate_duration_hours(dep_time, arr_time): + """Calculate flight duration in hours""" + try: + dep_dt = datetime.strptime(dep_time, '%Y-%m-%dT%H:%M') + arr_dt = datetime.strptime(arr_time, '%Y-%m-%dT%H:%M') + duration = arr_dt - dep_dt + return duration.total_seconds() / 3600 + except: + return 3.0 + +def prepare_features(form_data): + """Prepare features for model prediction""" + dep_features = extract_datetime_features(form_data['Dep_Time']) + arr_features = extract_datetime_features(form_data['Arrival_Time']) + duration_hours = calculate_duration_hours(form_data['Dep_Time'], form_data['Arrival_Time']) + + features = [ + AIRLINE_MAPPING.get(form_data['airline'], 0), + SOURCE_MAPPING.get(form_data['Source'], 0), + DESTINATION_MAPPING.get(form_data['Destination'], 0), + int(form_data['stops']), + dep_features['hour'], dep_features['day'], dep_features['month'], + dep_features['weekday'], dep_features['is_weekend'], + arr_features['hour'], arr_features['day'], arr_features['month'], + arr_features['weekday'], arr_features['is_weekend'], + duration_hours + ] + + return np.array(features).reshape(1, -1) + +@app.route('/') def home(): - return render_template("home.html") - + """Render the main form page""" + return render_template('index.html') - - -@app.route("/predict", methods = ["GET", "POST"]) -@cross_origin() +@app.route('/predict', methods=['POST']) def predict(): - if request.method == "POST": - - # Date_of_Journey - date_dep = request.form["Dep_Time"] - Journey_day = int(pd.to_datetime(date_dep, format="%Y-%m-%dT%H:%M").day) - Journey_month = int(pd.to_datetime(date_dep, format ="%Y-%m-%dT%H:%M").month) - # print("Journey Date : ",Journey_day, Journey_month) - - # Departure - Dep_hour = int(pd.to_datetime(date_dep, format ="%Y-%m-%dT%H:%M").hour) - Dep_min = int(pd.to_datetime(date_dep, format ="%Y-%m-%dT%H:%M").minute) - # print("Departure : ",Dep_hour, Dep_min) - - # Arrival - date_arr = request.form["Arrival_Time"] - Arrival_hour = int(pd.to_datetime(date_arr, format ="%Y-%m-%dT%H:%M").hour) - Arrival_min = int(pd.to_datetime(date_arr, format ="%Y-%m-%dT%H:%M").minute) - # print("Arrival : ", Arrival_hour, Arrival_min) - - # Duration - dur_hour = abs(Arrival_hour - Dep_hour) - dur_min = abs(Arrival_min - Dep_min) - # print("Duration : ", dur_hour, dur_min) - - # Total Stops - Total_stops = int(request.form["stops"]) - # print(Total_stops) - - # Airline - # AIR ASIA = 0 (not in column) - airline=request.form['airline'] - if(airline=='Jet Airways'): - Jet_Airways = 1 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='IndiGo'): - Jet_Airways = 0 - IndiGo = 1 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='Air India'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 1 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='Multiple carriers'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 1 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='SpiceJet'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 1 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='Vistara'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 1 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='GoAir'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 1 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='Multiple carriers Premium economy'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 1 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='Jet Airways Business'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 1 - Vistara_Premium_economy = 0 - Trujet = 0 - - elif (airline=='Vistara Premium economy'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 1 - Trujet = 0 - - elif (airline=='Trujet'): - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 1 - - else: - Jet_Airways = 0 - IndiGo = 0 - Air_India = 0 - Multiple_carriers = 0 - SpiceJet = 0 - Vistara = 0 - GoAir = 0 - Multiple_carriers_Premium_economy = 0 - Jet_Airways_Business = 0 - Vistara_Premium_economy = 0 - Trujet = 0 - - # print(Jet_Airways, - # IndiGo, - # Air_India, - # Multiple_carriers, - # SpiceJet, - # Vistara, - # GoAir, - # Multiple_carriers_Premium_economy, - # Jet_Airways_Business, - # Vistara_Premium_economy, - # Trujet) - - # Source - # Banglore = 0 (not in column) - Source = request.form["Source"] - if (Source == 'Delhi'): - s_Delhi = 1 - s_Kolkata = 0 - s_Mumbai = 0 - s_Chennai = 0 - - elif (Source == 'Kolkata'): - s_Delhi = 0 - s_Kolkata = 1 - s_Mumbai = 0 - s_Chennai = 0 - - elif (Source == 'Mumbai'): - s_Delhi = 0 - s_Kolkata = 0 - s_Mumbai = 1 - s_Chennai = 0 - - elif (Source == 'Chennai'): - s_Delhi = 0 - s_Kolkata = 0 - s_Mumbai = 0 - s_Chennai = 1 - - else: - s_Delhi = 0 - s_Kolkata = 0 - s_Mumbai = 0 - s_Chennai = 0 - - # print(s_Delhi, - # s_Kolkata, - # s_Mumbai, - # s_Chennai) - - # Destination - # Banglore = 0 (not in column) - Source = request.form["Destination"] - if (Source == 'Cochin'): - d_Cochin = 1 - d_Delhi = 0 - d_New_Delhi = 0 - d_Hyderabad = 0 - d_Kolkata = 0 - - elif (Source == 'Delhi'): - d_Cochin = 0 - d_Delhi = 1 - d_New_Delhi = 0 - d_Hyderabad = 0 - d_Kolkata = 0 - - elif (Source == 'New_Delhi'): - d_Cochin = 0 - d_Delhi = 0 - d_New_Delhi = 1 - d_Hyderabad = 0 - d_Kolkata = 0 - - elif (Source == 'Hyderabad'): - d_Cochin = 0 - d_Delhi = 0 - d_New_Delhi = 0 - d_Hyderabad = 1 - d_Kolkata = 0 - - elif (Source == 'Kolkata'): - d_Cochin = 0 - d_Delhi = 0 - d_New_Delhi = 0 - d_Hyderabad = 0 - d_Kolkata = 1 - - else: - d_Cochin = 0 - d_Delhi = 0 - d_New_Delhi = 0 - d_Hyderabad = 0 - d_Kolkata = 0 - - # print( - # d_Cochin, - # d_Delhi, - # d_New_Delhi, - # d_Hyderabad, - # d_Kolkata - # ) + """Handle prediction request""" + if model is None: + return render_template('predict.html', error="Model not loaded. Please check if flight_rf.pkl exists."), 500 + + try: + form_data = request.form.to_dict() + required_fields = ['Dep_Time', 'Arrival_Time', 'Source', 'Destination', 'stops', 'airline'] + for field in required_fields: + if field not in form_data or not form_data[field]: + return render_template('templates/predict.html', error=f"Missing required field: {field}"), 400 + + features = prepare_features(form_data) + prediction = model.predict(features)[0] + predicted_price = round(prediction, 2) - - # ['Total_Stops', 'Journey_day', 'Journey_month', 'Dep_hour', - # 'Dep_min', 'Arrival_hour', 'Arrival_min', 'Duration_hours', - # 'Duration_mins', 'Airline_Air India', 'Airline_GoAir', 'Airline_IndiGo', - # 'Airline_Jet Airways', 'Airline_Jet Airways Business', - # 'Airline_Multiple carriers', - # 'Airline_Multiple carriers Premium economy', 'Airline_SpiceJet', - # 'Airline_Trujet', 'Airline_Vistara', 'Airline_Vistara Premium economy', - # 'Source_Chennai', 'Source_Delhi', 'Source_Kolkata', 'Source_Mumbai', - # 'Destination_Cochin', 'Destination_Delhi', 'Destination_Hyderabad', - # 'Destination_Kolkata', 'Destination_New Delhi'] + response_data = { + 'prediction': f"₹{predicted_price:,.2f}", + 'source': form_data['Source'], + 'destination': form_data['Destination'], + 'departure_time': form_data['Dep_Time'], + 'arrival_time': form_data['Arrival_Time'], + 'stops': form_data['stops'], + 'airline': form_data['airline'], + 'duration': f"{calculate_duration_hours(form_data['Dep_Time'], form_data['Arrival_Time']):.1f} hours" + } - prediction=model.predict([[ - Total_stops, - Journey_day, - Journey_month, - Dep_hour, - Dep_min, - Arrival_hour, - Arrival_min, - dur_hour, - dur_min, - Air_India, - GoAir, - IndiGo, - Jet_Airways, - Jet_Airways_Business, - Multiple_carriers, - Multiple_carriers_Premium_economy, - SpiceJet, - Trujet, - Vistara, - Vistara_Premium_economy, - s_Chennai, - s_Delhi, - s_Kolkata, - s_Mumbai, - d_Cochin, - d_Delhi, - d_Hyderabad, - d_Kolkata, - d_New_Delhi - ]]) - - output=round(prediction[0],2) - - return render_template('home.html',prediction_text="Your Flight price is Rs. {}".format(output)) - - - return render_template("home.html") - - - - -if __name__ == "__main__": - app.run(debug=True) + return render_template('predict.html', **response_data) + + except Exception as e: + print(f"Prediction error: {str(e)}") + return render_template('error.html', error=f"Prediction failed: {str(e)}"), 500 + +@app.route('/api/predict', methods=['POST']) +def api_predict(): + """API endpoint for predictions (JSON response)""" + if model is None: + return jsonify({'error': 'Model not loaded', 'status': 'error'}), 500 + + try: + data = request.json + features = prepare_features(data) + prediction = model.predict(features)[0] + return jsonify({ + 'prediction': round(prediction, 2), + 'formatted_prediction': f"₹{prediction:,.2f}", + 'status': 'success' + }) + except Exception as e: + return jsonify({'error': str(e), 'status': 'error'}), 500 + +if __name__ == '__main__': + print("Starting Flight Price Prediction App...") + print("Make sure 'flight_rf.pkl' is in the same directory as this script.") + app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/templates/home.html b/templates/home.html index 3b48f81..f7e16bd 100644 --- a/templates/home.html +++ b/templates/home.html @@ -1,183 +1,420 @@ +