# Streamlit frontend for the Airbnb Rental Price Prediction service. # This UI collects property details from the user, sends them to the # deployed Flask backend, and displays the predicted rental price. import streamlit as st import pandas as pd import requests # ----------------------------------------------------------------------------- # Configure the backend API endpoints # ----------------------------------------------------------------------------- # Replace the base URL below with the URL of your deployed backend Space. MODEL_ROOT_URL = "https://uohna-RentalPricePredictionBackend.hf.space" ONLINE_URL = f"{MODEL_ROOT_URL}/v1/rental" BATCH_URL = f"{MODEL_ROOT_URL}/v1/rentalbatch" # ----------------------------------------------------------------------------- # Page configuration # ----------------------------------------------------------------------------- st.set_page_config( page_title="Airbnb Rental Price Predictor", page_icon="🏡", layout="centered", ) st.title("🏡 Airbnb Rental Price Predictor") st.write( "Predict the nightly rental price for a property using our deployed " "machine learning model." ) # Two tabs: one for single-property prediction, one for batch uploads online_tab, batch_tab = st.tabs(["Single Prediction", "Batch Prediction"]) # ----------------------------------------------------------------------------- # Online (single property) inference # ----------------------------------------------------------------------------- with online_tab: st.subheader("Enter Property Details") col1, col2 = st.columns(2) with col1: room_type = st.selectbox( "Room Type", ["Entire home/apt", "Private room", "Shared room"], ) accommodates = st.number_input( "Accommodates", min_value=1, max_value=20, value=2, step=1 ) bathrooms = st.number_input( "Bathrooms", min_value=0.0, max_value=10.0, value=1.0, step=0.5 ) bedrooms = st.number_input( "Bedrooms", min_value=0, max_value=15, value=1, step=1 ) beds = st.number_input( "Beds", min_value=0, max_value=20, value=1, step=1 ) with col2: cancellation_policy = st.selectbox( "Cancellation Policy", ["flexible", "moderate", "strict", "super_strict_30", "super_strict_60"], ) cleaning_fee = st.selectbox("Cleaning Fee Charged?", [True, False]) instant_bookable = st.selectbox("Instant Bookable?", ["t", "f"]) review_scores_rating = st.slider( "Review Scores Rating", min_value=0, max_value=100, value=90, step=1 ) if st.button("Predict Price", type="primary"): payload = { "room_type": room_type, "accommodates": int(accommodates), "bathrooms": float(bathrooms), "cancellation_policy": cancellation_policy, "cleaning_fee": bool(cleaning_fee), "instant_bookable": instant_bookable, "review_scores_rating": int(review_scores_rating), "bedrooms": int(bedrooms), "beds": int(beds), } try: response = requests.post(ONLINE_URL, json=payload, timeout=30) if response.status_code == 200: result = response.json() price = result.get("Predicted Price (in dollars)") st.success(f"💰 Predicted Nightly Price: **${price}**") else: st.error(f"Request failed ({response.status_code}): {response.text}") except requests.exceptions.RequestException as err: st.error(f"Could not reach the backend API: {err}") # ----------------------------------------------------------------------------- # Batch inference # ----------------------------------------------------------------------------- with batch_tab: st.subheader("Upload a CSV for Batch Predictions") st.caption( "Your CSV should contain the same feature columns the model was trained on " "(e.g., room_type, accommodates, bathrooms, cancellation_policy, cleaning_fee, " "instant_bookable, review_scores_rating, bedrooms, beds, and an 'id' column)." ) uploaded_file = st.file_uploader("Choose a CSV file", type=["csv"]) if uploaded_file is not None: df_preview = pd.read_csv(uploaded_file) st.write("Preview of uploaded data:") st.dataframe(df_preview.head()) if st.button("Run Batch Prediction"): # Rewind so we can send the raw CSV bytes uploaded_file.seek(0) try: response = requests.post( BATCH_URL, files={"file": uploaded_file.getvalue()}, timeout=120, ) if response.status_code == 200: predictions = response.json() st.success(f"✅ Received {len(predictions)} predictions.") results_df = pd.DataFrame( list(predictions.items()), columns=["Property ID", "Predicted Price (in dollars)"], ) st.dataframe(results_df) st.download_button( "Download Predictions as CSV", data=results_df.to_csv(index=False).encode("utf-8"), file_name="rental_price_predictions.csv", mime="text/csv", ) else: st.error( f"Request failed ({response.status_code}): {response.text}" ) except requests.exceptions.RequestException as err: st.error(f"Could not reach the backend API: {err}")