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("
๐Ÿก

House Price Predictor

") with gr.Tabs(): # ---- Tab 1: Predict ---- with gr.TabItem("๐Ÿ”ฎ Predict"): with gr.Row(): with gr.Column(): area = gr.Number(label="Area (sq ft)", value=2000, precision=0) parking = gr.Slider(0, 5, step=1, value=1, label="Parking Spots") bedrooms = gr.Slider(0, 10, step=1, value=3, label="Bedrooms") bathrooms = gr.Slider(0, 10, step=1, value=2, label="Bathrooms") stories = gr.Slider(0, 10, step=1, value=2, label="Stories") with gr.Column(): furnishingstatus = gr.Dropdown(FURN, value="semi-furnished", label="Furnishing Status") mainroad = gr.Dropdown(YES_NO, value="yes", label="On Main Road?") guestroom = gr.Dropdown(YES_NO, value="no", label="Guest Room?") basement = gr.Dropdown(YES_NO, value="no", label="Basement?") with gr.Column(): hotwaterheating = gr.Dropdown(YES_NO, value="no", label="Hot Water Heating?") airconditioning = gr.Dropdown(YES_NO, value="yes", label="Air Conditioning?") prefarea = gr.Dropdown(YES_NO, value="no", label="Preferred Area?") with gr.Row(): predict_btn = gr.Button("โœจ Predict", size="lg") out = gr.Number(label="Predicted Price", precision=1) predict_btn.click( fn=predict, inputs=[area, parking, bedrooms, bathrooms, stories, furnishingstatus, mainroad, guestroom, basement, hotwaterheating, airconditioning, prefarea], outputs=out ) # ---- Tab 2: What-if ---- with gr.TabItem("๐Ÿงช What-if"): gr.Markdown("Explore how price changes as **area** varies (other inputs fixed).") with gr.Row(): with gr.Column(scale=4): wi_parking = gr.Slider(0, 5, step=1, value=1, label="Parking Spots") wi_bedrooms = gr.Slider(0, 10, step=1, value=3, label="Bedrooms") wi_bathrooms = gr.Slider(0, 10, step=1, value=2, label="Bathrooms") wi_stories = gr.Slider(0, 10, step=1, value=2, label="Stories") with gr.Column(scale=3): wi_furnishingstatus = gr.Dropdown(FURN, value="semi-furnished", label="Furnishing Status") wi_mainroad = gr.Dropdown(YES_NO, value="yes", label="On Main Road?") wi_guestroom = gr.Dropdown(YES_NO, value="no", label="Guest Room?") wi_basement = gr.Dropdown(YES_NO, value="no", label="Basement?") with gr.Column(scale=2): wi_hotwater = gr.Dropdown(YES_NO, value="no", label="Hot Water Heating?") wi_ac = gr.Dropdown(YES_NO, value="yes", label="Air Conditioning?") wi_prefarea = gr.Dropdown(YES_NO, value="no", label="Preferred Area?") with gr.Column(scale=1): area_min = gr.Number(label="Area min", value=500, precision=0) area_max = gr.Number(label="Area max", value=5000, precision=0) steps = gr.Slider(10, 200, value=50, step=1, label="Steps (resolution)") plot_btn = gr.Button("๐Ÿ“ˆ Generate curve", size="lg") fig = gr.Plot(label="Prediction vs Area") plot_btn.click( fn=what_if_plot, inputs=[wi_parking, wi_bedrooms, wi_bathrooms, wi_stories, wi_furnishingstatus, wi_mainroad, wi_guestroom, wi_basement, wi_hotwater, wi_ac, wi_prefarea, area_min, area_max, steps], outputs=fig ) demo.launch( server_name="0.0.0.0", server_port=int(os.getenv("PORT", "7860")), # ssr_mode=False, # optional: disable the experimental SSR note )