nivakaran's picture
Update app.py
54d766b verified
import gradio as gr
import joblib
import numpy as np
import pandas as pd
import os
import sys
# MongoDB and environment setup
import certifi
ca = certifi.where()
from dotenv import load_dotenv
load_dotenv()
mongo_db_url = os.getenv("MONGO_DB_URL")
import pymongo
from src.exception.exception import DeliveryTimeException
from src.logging.logger import logging
from src.pipeline.training_pipeline import TrainingPipeline
from src.utils.main_utils.utils import load_object
from src.utils.ml_utils.model.estimator import DeliveryPredictionModel
# MongoDB client setup
try:
client = pymongo.MongoClient(mongo_db_url, tlsCAFile=ca)
from src.constants.training_pipeline import DATA_INGESTION_COLLECTION_NAME
from src.constants.training_pipeline import DATA_INGESTION_DATABASE_NAME
database = client[DATA_INGESTION_DATABASE_NAME]
collection = database[DATA_INGESTION_COLLECTION_NAME]
except Exception as e:
logging.warning(f"MongoDB connection failed: {e}. Continuing without database.")
client = None
# Feature list
TOP_12_FEATURES = [
'multiple_deliveries', 'Road_traffic_density', 'Vehicle_condition', 'Delivery_person_Ratings',
'distance_deliveries', 'Weather_conditions', 'Festival', 'distance_traffic', 'distance',
'Delivery_person_Age', 'prep_traffic', 'City'
]
# Mapping dictionaries for dropdowns
WEATHER_CONDITIONS = {'Sunny': 0, 'Cloudy': 1, 'Fog': 2, 'Sandstorms': 3, 'Stormy': 4, 'Windy': 5}
TRAFFIC_DENSITY = {'Low': 0, 'Medium': 1, 'High': 2, 'Jam': 3}
VEHICLE_CONDITION = {'Poor': 0, 'Good': 1, 'Excellent': 2}
FESTIVAL = {'No': 0, 'Yes': 1}
CITY = {'Urban': 0, 'Semi-Urban': 1, 'Metropolitan': 2}
# Load model and scaler
try:
model = joblib.load('final_model/model.pkl')
preprocessor = joblib.load('final_model/preprocessor.pkl')
scaler = preprocessor['scaler']
expected_features = preprocessor['feature_names']
logging.info("Model and scaler loaded successfully")
except Exception as e:
logging.error(f"Error loading model or scaler: {e}")
raise e
def train_model():
"""Function to train the model"""
try:
train_pipeline = TrainingPipeline()
train_pipeline.run_pipeline()
return "Training completed successfully!"
except Exception as e:
logging.error(f"Error in training pipeline: {e}")
return f"Training failed: {str(e)}"
def predict_delivery_time(
multiple_deliveries,
road_traffic_density,
vehicle_condition,
delivery_person_ratings,
distance_deliveries,
weather_conditions,
festival,
distance_traffic,
distance,
delivery_person_age,
prep_traffic,
city
):
"""
Predict delivery time based on input features
"""
try:
# Validate and convert inputs
input_data = {
'multiple_deliveries': float(multiple_deliveries),
'Road_traffic_density': TRAFFIC_DENSITY[road_traffic_density],
'Vehicle_condition': VEHICLE_CONDITION[vehicle_condition],
'Delivery_person_Ratings': float(delivery_person_ratings),
'distance_deliveries': float(distance_deliveries),
'Weather_conditions': WEATHER_CONDITIONS[weather_conditions],
'Festival': FESTIVAL[festival],
'distance_traffic': float(distance_traffic),
'distance': float(distance),
'Delivery_person_Age': float(delivery_person_age),
'prep_traffic': float(prep_traffic),
'City': CITY[city]
}
# Create DataFrame and ensure correct feature order
df = pd.DataFrame([input_data])
df = df[expected_features]
# Scale features
features_scaled = scaler.transform(df)
# Make prediction
if hasattr(model, 'predict'):
prediction = model.predict(features_scaled)
else:
prediction = model.model.predict(features_scaled)
# Convert to scalar
if isinstance(prediction, np.ndarray):
prediction = float(prediction[0])
else:
prediction = float(prediction)
logging.info(f"Prediction: {prediction}")
return f"๐Ÿ•’ Estimated Delivery Time: **{round(prediction, 2)} minutes** ({round(prediction/60, 2)} hours)"
except Exception as e:
logging.error(f"Error in prediction: {e}")
return f"โŒ Error: {str(e)}"
# Create Gradio Interface
with gr.Blocks(title="Delivery Time Prediction", theme=gr.themes.Soft()) as demo:
gr.Markdown(
"""
# ๐Ÿšš Delivery Time Prediction System
### Predict estimated delivery time based on various factors
Enter the delivery details below to get an estimated delivery time.
"""
)
with gr.Tab("Prediction"):
with gr.Row():
with gr.Column():
gr.Markdown("### ๐Ÿ“ฆ Delivery Details")
multiple_deliveries = gr.Number(
label="Multiple Deliveries",
value=1,
minimum=1,
maximum=10,
info="Number of deliveries in the order"
)
distance = gr.Number(
label="Distance (km)",
value=5.0,
minimum=0,
info="Total delivery distance"
)
distance_deliveries = gr.Number(
label="Distance for Deliveries (km)",
value=5.0,
minimum=0
)
distance_traffic = gr.Number(
label="Distance in Traffic (km)",
value=2.0,
minimum=0
)
prep_traffic = gr.Number(
label="Preparation Time in Traffic (min)",
value=10.0,
minimum=0
)
with gr.Column():
gr.Markdown("### ๐Ÿ‘ค Delivery Person Details")
delivery_person_age = gr.Number(
label="Delivery Person Age",
value=25,
minimum=18,
maximum=65
)
delivery_person_ratings = gr.Slider(
label="Delivery Person Rating",
minimum=1.0,
maximum=5.0,
value=4.5,
step=0.1
)
vehicle_condition = gr.Dropdown(
label="Vehicle Condition",
choices=list(VEHICLE_CONDITION.keys()),
value="Good"
)
with gr.Column():
gr.Markdown("### ๐ŸŒ Environmental Conditions")
weather_conditions = gr.Dropdown(
label="Weather Conditions",
choices=list(WEATHER_CONDITIONS.keys()),
value="Sunny"
)
road_traffic_density = gr.Dropdown(
label="Road Traffic Density",
choices=list(TRAFFIC_DENSITY.keys()),
value="Medium"
)
city = gr.Dropdown(
label="City Type",
choices=list(CITY.keys()),
value="Urban"
)
festival = gr.Radio(
label="Festival Day?",
choices=list(FESTIVAL.keys()),
value="No"
)
with gr.Row():
predict_btn = gr.Button("๐Ÿ”ฎ Predict Delivery Time", variant="primary", size="lg")
clear_btn = gr.ClearButton(components=[
multiple_deliveries, road_traffic_density, vehicle_condition,
delivery_person_ratings, distance_deliveries, weather_conditions,
festival, distance_traffic, distance, delivery_person_age,
prep_traffic, city
], value="๐Ÿ”„ Clear")
output = gr.Markdown(label="Prediction Result")
predict_btn.click(
fn=predict_delivery_time,
inputs=[
multiple_deliveries, road_traffic_density, vehicle_condition,
delivery_person_ratings, distance_deliveries, weather_conditions,
festival, distance_traffic, distance, delivery_person_age,
prep_traffic, city
],
outputs=output
)
with gr.Tab("Training"):
gr.Markdown(
"""
## ๐ŸŽ“ Model Training
Click the button below to retrain the model with the latest data from MongoDB.
"""
)
train_btn = gr.Button("๐Ÿš€ Start Training", variant="primary")
train_output = gr.Textbox(label="Training Status", lines=3)
train_btn.click(
fn=train_model,
inputs=[],
outputs=train_output
)
with gr.Tab("About"):
gr.Markdown(
"""
## ๐Ÿ“Š About This Application
This delivery time prediction system uses machine learning to estimate delivery times based on:
- **Delivery Details**: Number of deliveries, distances
- **Delivery Person**: Age, ratings, vehicle condition
- **Environment**: Weather, traffic density, city type, festival days
### Features Used
The model considers 12 key features to make accurate predictions:
1. Multiple Deliveries
2. Road Traffic Density
3. Vehicle Condition
4. Delivery Person Ratings
5. Distance for Deliveries
6. Weather Conditions
7. Festival Day
8. Distance in Traffic
9. Total Distance
10. Delivery Person Age
11. Preparation Time in Traffic
12. City Type
### How to Use
1. Enter all the required delivery details in the **Prediction** tab
2. Click the "Predict Delivery Time" button
3. View the estimated delivery time in minutes and hours
### Model Training
Use the **Training** tab to retrain the model with new data from the database.
"""
)
# Launch the app
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860, # Default port for Hugging Face Spaces
share=False
)