|
|
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") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def resolve_backend_url() -> str: |
|
|
|
|
|
return (os.getenv("BACKEND_URL") or "https://rizwan9-backend.hf.space").strip() |
|
|
|
|
|
BACKEND_URL = resolve_backend_url() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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"]) |
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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: |
|
|
|
|
|
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}") |