zkmine's picture
Update app.py
4526c26 verified
# AI Assistance Declaration:
# Parts of this script were assisted by ChatGPT GPT.
# AI assistance was limited to code suggestions, debugging tips, or documentation wording.
# All algorithmic design, implementation decisions, and final code structure were created and verified by the project team.
import gradio as gr
import requests
# Cloud Run API URL
API_BASE = "https://ecommerce-ml-346297770564.us-east1.run.app"
# Numeric features
numeric_features = {
"shipping_fee": 6,
"tax": 6,
"avg_order_value": 6,
"day_of_week": 6
}
# Binary features (0/1) but UI uses "Yes"/"No"
binary_features = {
"status_cancelled": 1,
"status_completed": 1,
"status_processing": 1,
"status_returned": 0,
"status_shipped": 1,
"is_holiday": 1
}
# Create widgets
numeric_inputs = [
gr.Number(label=f"📊 {f.replace('_',' ').title()}", value=v)
for f, v in numeric_features.items()
]
binary_inputs = [
gr.Radio(
label=f"🔘 {f.replace('_',' ').title()}",
choices=["Yes (1)", "No (0)"],
value="Yes (1)" if v == 1 else "No (0)"
)
for f, v in binary_features.items()
]
feature_names = list(numeric_features.keys()) + list(binary_features.keys())
all_inputs = numeric_inputs + binary_inputs
def parse_value(v):
if isinstance(v, str):
return 1 if "Yes" in v else 0
return v
def predict_fn(*values):
parsed_vals = [parse_value(v) for v in values]
features = {f: v for f, v in zip(feature_names, parsed_vals)}
payload = {"features": features}
response = requests.post(f"{API_BASE}/predict", json=payload)
if response.status_code != 200:
return f"❌ API Error: {response.text}"
preds = response.json()["predictions"]
# prediction UI
html = """
<div style='
background: #f9fafb;
border-left: 6px solid #4f46e5;
padding: 15px 20px;
border-radius: 10px;
font-size: 16px;
'>
<h3 style='margin-top: 0; color: #4f46e5;'>📦 Prediction Results</h3>
"""
for k, v in preds.items():
html += f"""
<p><b>{k}:</b> {v:.4f}</p>
"""
html += "</div>"
return html
def reset_inputs():
merged = list(numeric_features.values()) + list(binary_features.values())
return [
v if isinstance(v, (int, float)) else ("Yes (1)" if v == 1 else "No (0)")
for v in merged
]
# UI with Blocks
with gr.Blocks() as demo:
gr.HTML("""
<style>
.gradio-container {
max-width: 900px !important;
margin: auto !important;
}
</style>
""")
gr.Markdown("## 🚀 **E-commerce Sales Forecast Demo**")
gr.Markdown(
"Enter feature values below. Boolean features use **Yes/No** but backend receives **1/0**.\n"
"Click **Predict** to get results from the model deployed on **Google Cloud Run**."
)
with gr.Row():
with gr.Column():
gr.Markdown("### 📊 Numeric Features")
for widget in numeric_inputs:
widget.render()
gr.Markdown("---")
gr.Markdown("### 🔘 Binary Features (Yes / No)")
for widget in binary_inputs:
widget.render()
with gr.Column():
result_box = gr.HTML(label="📦 Predictions")
with gr.Row():
predict_btn = gr.Button("🔮 Predict", variant="primary")
reset_btn = gr.Button("♻️ Reset")
predict_btn.click(fn=predict_fn, inputs=all_inputs, outputs=result_box)
reset_btn.click(fn=lambda: reset_inputs(), inputs=None, outputs=all_inputs)
gr.Markdown("This interface communicates with a FastAPI backend deployed on **Cloud Run**.")
demo.launch()