import streamlit as st import pandas as pd import pickle import os import warnings warnings.filterwarnings("ignore") # ────────────────────────────────────────────── # PAGE CONFIG # ────────────────────────────────────────────── st.set_page_config( page_title="House Price AI", page_icon="🏠", layout="centered", initial_sidebar_state="auto", ) # ────────────────────────────────────────────── # CSS LOADER ← reads from static/css/style.css # ────────────────────────────────────────────── def load_css(): """ Reads the external stylesheet from static/css/style.css and injects it into the Streamlit page via st.markdown. All visual styling lives in that file — app.py stays clean. """ css_path = os.path.join("static", "css", "style.css") if not os.path.exists(css_path): st.warning("⚠️ style.css not found — place it at static/css/style.css") return with open(css_path, "r", encoding="utf-8") as f: css_content = f.read() st.markdown(f"", unsafe_allow_html=True) load_css() # ────────────────────────────────────────────── # DATA & MODEL # ────────────────────────────────────────────── DATA_PATH = "data_updated_ap_kakinada.csv" MODEL_PATH = "model.pkl" if not os.path.exists(DATA_PATH): st.error("❌ Dataset file not found! Expected: data_updated_ap_kakinada.csv") st.stop() if not os.path.exists(MODEL_PATH): st.error("❌ Model file not found! Expected: model.pkl") st.stop() df = pd.read_csv(DATA_PATH) with open(MODEL_PATH, "rb") as f: model = pickle.load(f) # ────────────────────────────────────────────── # SESSION STATE # ────────────────────────────────────────────── if "logged_in" not in st.session_state: st.session_state.logged_in = False if "username" not in st.session_state: st.session_state.username = "" # ────────────────────────────────────────────── # HELPER: render HTML card wrapper # ────────────────────────────────────────────── def card_open(extra_class=""): st.markdown(f'
', unsafe_allow_html=True) def card_close(): st.markdown("
", unsafe_allow_html=True) # ────────────────────────────────────────────── # PAGE: LOGIN # ────────────────────────────────────────────── def login(): # Hero header st.markdown("""
AI-Powered · Real-time Estimates

Welcome Back

Sign in to your House Price AI account

""", unsafe_allow_html=True) card_open() username = st.text_input("Username", placeholder="Enter your username") password = st.text_input("Password", type="password", placeholder="Enter your password") if st.button("🔐 Sign In"): if username and password: st.session_state.logged_in = True st.session_state.username = username st.success("✅ Login successful! Redirecting…") st.rerun() else: st.error("❌ Please enter both username and password.") st.markdown("""

Don't have an account?  Use the sidebar → Signup

""", unsafe_allow_html=True) card_close() # ────────────────────────────────────────────── # PAGE: SIGNUP # ────────────────────────────────────────────── def signup(): st.markdown("""

Create Account

Start predicting house prices in seconds

""", unsafe_allow_html=True) card_open() username = st.text_input("Username", placeholder="Choose a username") password = st.text_input("Password", type="password", placeholder="Create a strong password") confirm = st.text_input("Confirm Password", type="password", placeholder="Repeat your password") if st.button("✨ Create Account"): if not username or not password or not confirm: st.error("❌ All fields are required.") elif password != confirm: st.error("❌ Passwords do not match.") elif len(password) < 6: st.warning("⚠️ Password should be at least 6 characters.") else: st.success("✅ Account created! Please log in.") st.markdown("""

Already have an account?  Use the sidebar → Login

""", unsafe_allow_html=True) card_close() # ────────────────────────────────────────────── # PAGE: DASHBOARD # ────────────────────────────────────────────── def dashboard(): # ── SIDEBAR ────────────────────────────── with st.sidebar: st.markdown("""
🏠
House Price AI
""", unsafe_allow_html=True) st.markdown(f"""
{st.session_state.username[:1].upper() if st.session_state.username else "G"}
{st.session_state.username or "Guest"}
Signed in
""", unsafe_allow_html=True) st.markdown("---") if st.button("🚪 Sign Out"): st.session_state.logged_in = False st.session_state.username = "" st.rerun() # ── HERO ───────────────────────────────── st.markdown(f"""
AI-Powered · Real-time Estimates

House Price
Predictor

Enter city and area details to get an instant AI-powered price estimate for any property.

""", unsafe_allow_html=True) # ── STAT CARDS ─────────────────────────── col1, col2, col3 = st.columns(3) with col1: st.markdown("""
🏙️
500+
Cities Covered
""", unsafe_allow_html=True) with col2: st.markdown("""
📊
98.2%
Accuracy Rate
""", unsafe_allow_html=True) with col3: st.markdown("""
⚡
<1s
Response Time
""", unsafe_allow_html=True) st.markdown("
", unsafe_allow_html=True) # ── PREDICT FORM ───────────────────────── card_open() st.markdown("""
📍 Get Price Estimate
Fill in the property details below
""", unsafe_allow_html=True) cities = sorted(df["city"].unique()) if "city" in df.columns else ["Kakinada"] city = st.selectbox("City", cities, help="Select the city where the property is located") sqft = st.number_input( "Area (sq ft)", min_value=100.0, max_value=50000.0, step=50.0, help="Enter the total built-up area in square feet", ) predict_clicked = st.button("🔍 Predict Price") card_close() # ── RESULT ─────────────────────────────── if predict_clicked: if sqft < 100: st.error("❌ Please enter a valid area (minimum 100 sq ft).") else: try: with st.spinner("Calculating estimate…"): prediction = model.predict([[sqft]])[0] price = round(prediction, 2) price_sqft = round(price / sqft, 2) card_open() st.markdown(f"""
💰 Predicted Market Price
₹{price:,.2f}
Based on current market trends · {city}
📍 City {city}
📐 Area {sqft:,.0f} sq ft
📈 Price per sq ft ₹{price_sqft:,.2f}
""", unsafe_allow_html=True) card_close() except Exception as e: st.error(f"❌ Prediction error: {e}") # ── DATASET PREVIEW ────────────────────── st.markdown("
", unsafe_allow_html=True) card_open() st.markdown("""
📊 Dataset Preview
Showing first 10 rows of the training data
""", unsafe_allow_html=True) st.dataframe(df.head(10), use_container_width=True) card_close() # ────────────────────────────────────────────── # ROUTING # ────────────────────────────────────────────── if st.session_state.logged_in: dashboard() else: with st.sidebar: st.markdown("""
🏠
House Price AI
""", unsafe_allow_html=True) choice = st.selectbox("", ["Login", "Sign Up"], label_visibility="collapsed") if choice == "Login": login() else: signup()