Spaces:
Sleeping
Sleeping
| 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 | |
| ) |