import os import streamlit as st import requests import pandas as pd st.set_page_config(page_title="🛒 SuperKart Sales Forecast", layout="centered") st.title("SuperKart Sales Forecast") st.caption("Frontend powered by Streamlit → calls Flask backend for predictions") # ----------------------------- # Backend URL (no st.secrets) # ----------------------------- def resolve_backend_url() -> str: # Use HF Space variable if set, else fallback to your backend return (os.getenv("BACKEND_URL") or "https://rizwan9-backend.hf.space").strip() BACKEND_URL = resolve_backend_url() # ----------------------------- # Sidebar: Backend Health # ----------------------------- st.sidebar.title("⚙️ Backend") backend_url_input = st.sidebar.text_input("Backend URL", value=BACKEND_URL) BACKEND_URL = backend_url_input.strip() or BACKEND_URL st.sidebar.markdown(f"**URL:** [{BACKEND_URL}]({BACKEND_URL})") @st.cache_data(ttl=60, show_spinner=False) def check_backend_health(url: str, timeout: int = 45): try: r = requests.get(f"{url}/health", timeout=timeout) return r.status_code, r.text except Exception as e: return None, str(e) status_box = st.sidebar.empty() auto_check = st.sidebar.toggle("Auto check health on load", value=True) def run_health_check(): with status_box, st.spinner("Checking backend health..."): code, msg = check_backend_health(BACKEND_URL) if code == 200: status_box.success("✅ Healthy (200)") elif code is None: status_box.error(f"❌ Unreachable\n{msg}") else: status_box.warning(f"⚠️ Status {code}\n{msg}") if auto_check: run_health_check() if st.sidebar.button("🔍 Check Health Now"): check_backend_health.clear() run_health_check() # ----------------------------- # Form # ----------------------------- st.divider() st.subheader("Enter Product and Store Details") with st.form("input_form"): col1, col2 = st.columns(2) with col1: Product_Weight = st.number_input("Product Weight", min_value=0.0, step=0.1) Product_Allocated_Area = st.number_input("Product Allocated Area", min_value=0.0, step=0.001, format="%.3f") Product_MRP = st.number_input("Product MRP", min_value=0.0, step=0.5) Store_Establishment_Year = st.number_input("Store Establishment Year", min_value=1950, max_value=2025, step=1) with col2: Product_Sugar_Content = st.selectbox("Product Sugar Content", ["Low Sugar", "Regular", "No Sugar"]) # note the lowercase "and" to match dataset Product_Type = st.selectbox("Product Type", [ "Meat","Snack Foods","Hard Drinks","Dairy","Canned","Soft Drinks","Health and Hygiene", "Baking Goods","Bread","Breakfast","Frozen Foods","Fruits and Vegetables","Household", "Seafood","Starchy Foods","Others" ]) Store_Size = st.selectbox("Store Size", ["Low","Medium","High"]) Store_Location_City_Type = st.selectbox("City Tier", ["Tier 1","Tier 2","Tier 3"]) Store_Type = st.selectbox("Store Type", ["Departmental Store","Supermarket Type 1","Supermarket Type 2","Food Mart"]) submitted = st.form_submit_button("🚀 Predict Sales") # ----------------------------- # Call backend # ----------------------------- if submitted: payload = { "Product_Weight": Product_Weight, "Product_Sugar_Content": Product_Sugar_Content, "Product_Allocated_Area": Product_Allocated_Area, "Product_Type": Product_Type, "Product_MRP": Product_MRP, "Store_Establishment_Year": int(Store_Establishment_Year), "Store_Size": Store_Size, "Store_Location_City_Type": Store_Location_City_Type, "Store_Type": Store_Type } try: with st.spinner("Fetching prediction from backend..."): r = requests.post(f"{BACKEND_URL}/predict", json=payload, timeout=60) if r.status_code != 200: # show backend's detailed message to make debugging easy try: st.error(f"❌ Prediction failed ({r.status_code}):\n\n{r.json()}") except Exception: st.error(f"❌ Prediction failed ({r.status_code}):\n\n{r.text}") else: prediction = r.json()["predictions"][0] st.success(f"📈 Predicted Product Store Sales Total: **{prediction:,.2f}**") except Exception as e: st.error(f"❌ Prediction failed:\n\n{e}")