madchavez's picture
change back
48194a4
Raw
History Blame Contribute Delete
5.03 kB
"""
Gradio demo app β€” HF Spaces compatible (place this file at repo root).
In local mode it hits the FastAPI server at API_URL.
For HF Spaces, set the HF_API_URL secret or update API_URL to your deployed endpoint.
Start locally:
# Terminal 1: uv run uvicorn serving.api:app --port 8000
# Terminal 2: uv run python app.py
"""
from __future__ import annotations
import os
import gradio as gr
import requests
API_URL = os.getenv("HF_API_URL", "http://localhost:8000")
PRIMARY_USAGE_MAP = {
"Work / Productivity (1)": 1,
"Gaming (2)": 2,
"Study / Education (3)": 3,
"Personal / Entertainment (4)": 4,
}
BRAND_MAP = {
"Brand A (1)": 1,
"Brand B (2)": 2,
"Brand C (3)": 3,
"Brand D (4)": 4,
"Brand E (5)": 5,
}
def predict(
hours_per_day: float,
cost: float,
user_age: float,
primary_usage: str,
brand: str,
computer_age_months: float,
) -> tuple[str, str]:
payload = {
"hours_used_per_day": hours_per_day,
"cost": cost,
"user_age": user_age,
"primary_usage": PRIMARY_USAGE_MAP[primary_usage],
"brand": BRAND_MAP[brand],
"computer_age_months": computer_age_months,
}
try:
resp = requests.post(f"{API_URL}/predict", json=payload, timeout=10)
resp.raise_for_status()
data = resp.json()
except requests.exceptions.ConnectionError:
return (
"❌ Cannot connect to the prediction API.",
f"Make sure the FastAPI server is running at {API_URL}\n\n"
"Run: uv run uvicorn serving.api:app --port 8000",
)
except Exception as exc:
return "❌ Error", str(exc)
prob = data["probability"]
label = data["needs_replacement"]
version = data.get("model_version", "N/A")
verdict = "πŸ”΄ **Replacement Recommended**" if label else "🟒 **No Replacement Needed**"
details = (
f"**Replacement Probability:** {prob:.1%}\n\n"
f"**Decision Threshold:** 50%\n\n"
f"**Model:** {version}\n\n"
f"---\n"
f"*Inputs:* {hours_per_day:.1f}h/day Β· ${cost:,.0f} Β· "
f"{user_age:.0f}yo Β· {computer_age_months:.0f} months old"
)
return verdict, details
def build_demo() -> gr.Blocks:
with gr.Blocks(
title="Computer Durability Predictor",
theme=gr.themes.Soft(),
) as demo:
gr.Markdown(
"""
# πŸ’» Computer Durability Predictor
**MLOps End-to-End Pipeline** Β· Dagster Β· MLflow Β· Evidently Β· FastAPI Β· Gradio
Predict whether a computer **needs replacement** based on its usage profile.
The model was trained on the Computer Durability dataset using
**XGBoost + Optuna** hyperparameter tuning and tracked with **MLflow**.
"""
)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### Usage & Hardware")
hours = gr.Slider(
label="Hours Used Per Day",
minimum=1.0, maximum=24.0, step=0.5, value=10.0,
)
cost = gr.Slider(
label="Computer Cost (USD)",
minimum=5000, maximum=50000, step=500, value=30000,
)
comp_age = gr.Slider(
label="Computer Age (Months)",
minimum=1, maximum=60, step=1, value=24,
)
with gr.Column(scale=1):
gr.Markdown("### User Profile")
user_age = gr.Slider(
label="User Age (Years)",
minimum=8, maximum=65, step=1, value=35,
)
usage_type = gr.Dropdown(
label="Primary Usage",
choices=list(PRIMARY_USAGE_MAP.keys()),
value="Work / Productivity (1)",
)
brand = gr.Dropdown(
label="Brand",
choices=list(BRAND_MAP.keys()),
value="Brand C (3)",
)
predict_btn = gr.Button("Predict", variant="primary", size="lg")
with gr.Row():
verdict_out = gr.Markdown(label="Verdict")
details_out = gr.Markdown(label="Details")
predict_btn.click(
fn=predict,
inputs=[hours, cost, user_age, usage_type, brand, comp_age],
outputs=[verdict_out, details_out],
)
gr.Markdown(
"""
---
### Architecture
```
CSV Data β†’ Dagster Pipeline β†’ MLflow (tracking + registry)
β†’ Evidently (drift + quality reports)
β†’ FastAPI β†’ Gradio (this app)
```
**Key signals driving replacement probability:**
- Hours/day > 12 β†’ risk increases significantly
- Cost < $20k β†’ cheaper machines fail more often
- Older users (>40) β†’ slight additional risk
"""
)
return demo
if __name__ == "__main__":
demo = build_demo()
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)