import os import gradio as gr import pandas as pd # --- tolerant loader (joblib -> pickle) --- def load_pickle(path): try: import joblib as jb return jb.load(path) except Exception: import pickle with open(path, "rb") as f: return pickle.load(f) MODEL_PATH = "HousePricePredictorPipeline.pkl" pipe = None err = None try: assert os.path.exists(MODEL_PATH), ( f"Model file not found: {MODEL_PATH}. " "Please place your trained pipeline (.pkl) next to app.py." ) pipe = load_pickle(MODEL_PATH) except Exception as e: err = str(e) if pipe is None: # Fail fast with a readable message raise RuntimeError( "Could not load the trained model pipeline.\n\n" f"Reason: {err}\n\n" "Make sure the file exists and was saved with a compatible sklearn/joblib version." ) # --- UI config --- NUM = ["area","parking","bedrooms","bathrooms","stories"] CAT = ["furnishingstatus","mainroad","guestroom","basement", "hotwaterheating","airconditioning","prefarea"] ALL = NUM + CAT YES_NO = ["yes","no"] FURN = ["unfurnished","semi-furnished","furnished"] # --- prediction fn --- def predict(area, parking, bedrooms, bathrooms, stories, furnishingstatus, mainroad, guestroom, basement, hotwaterheating, airconditioning, prefarea): X = pd.DataFrame([{ "area": area, "parking": int(parking), "bedrooms": int(bedrooms), "bathrooms": int(bathrooms), "stories": int(stories), "furnishingstatus": furnishingstatus, "mainroad": mainroad, "guestroom": guestroom, "basement": basement, "hotwaterheating": hotwaterheating, "airconditioning": airconditioning, "prefarea": prefarea }], columns=ALL) return float(pipe.predict(X)[0]) # --- optional: what-if curve (uses loaded model only) --- def what_if_plot(parking, bedrooms, bathrooms, stories, furnishingstatus, mainroad, guestroom, basement, hotwaterheating, airconditioning, prefarea, area_min, area_max, steps): import numpy as np import plotly.graph_objects as go areas = np.linspace(area_min, area_max, int(steps)) df = pd.DataFrame([{ "area": a, "parking": int(parking), "bedrooms": int(bedrooms), "bathrooms": int(bathrooms), "stories": int(stories), "furnishingstatus": furnishingstatus, "mainroad": mainroad, "guestroom": guestroom, "basement": basement, "hotwaterheating": hotwaterheating, "airconditioning": airconditioning, "prefarea": prefarea } for a in areas], columns=ALL) preds = pipe.predict(df) fig = go.Figure() fig.add_trace(go.Scatter(x=areas, y=preds, mode="lines+markers", name="Predicted price")) fig.update_layout( title="What-if analysis: vary Area (sq ft)", xaxis_title="Area (sq ft)", yaxis_title="Predicted price (model units)", template="plotly_white", hovermode="x unified", margin=dict(l=40, r=20, t=60, b=40), ) return fig # --- Theme & CSS --- theme = gr.themes.Soft( primary_hue="emerald", secondary_hue="blue", ).set( border_color_primary="rgba(0,0,0,0.1)", body_background_fill="linear-gradient(135deg, #e0f2fe, #f0fdf4)", block_background_fill="rgba(255,255,255,0.6)", ) custom_css = """ /* --- Animated gradient background --- */ body { background: linear-gradient(135deg, #1e3a8a, #2563eb, #06b6d4, #10b981); background-size: 400% 400%; animation: gradientMove 15s ease infinite; color: #111827; } @keyframes gradientMove { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } /* --- App title with neon gradient glow --- */ #app-title h1 { font-size: 2.5rem; font-weight: 900; background: linear-gradient(90deg, #f59e0b, #ec4899, #6366f1); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-shadow: 0 0 25px rgba(236, 72, 153, 0.3); letter-spacing: 1.2px; text-align: center; margin-bottom: 1rem; } /* --- Glass panels --- */ .gr-panel { border-radius: 20px !important; background: rgba(255, 255, 255, 0.2) !important; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); backdrop-filter: blur(16px); border: 1px solid rgba(255, 255, 255, 0.25); transition: all 0.25s ease; } .gr-panel:hover { transform: translateY(-3px); box-shadow: 0 12px 36px rgba(0, 0, 0, 0.25); } /* --- Buttons --- */ button { border-radius: 12px !important; font-weight: 600 !important; background: linear-gradient(90deg, #3b82f6, #10b981) !important; color: white !important; transition: all 0.25s ease !important; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); } button:hover { background: linear-gradient(90deg, #06b6d4, #6366f1) !important; transform: scale(1.05); box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4); } /* --- Tabs & inputs --- */ .gradio-tab { background: rgba(255, 255, 255, 0.4); border-radius: 18px; padding: 10px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); } input, select, textarea { border-radius: 8px !important; border: 1px solid rgba(99, 102, 241, 0.3) !important; } /* --- Slider thumb accent --- */ input[type=range]::-webkit-slider-thumb { background: #06b6d4 !important; border: 2px solid white; } """ with gr.Blocks(theme=theme, css=custom_css, title="House Price Predictor") as demo: gr.Markdown("