Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -213,22 +213,17 @@ def load_kpis() -> Dict[str, Any]:
|
|
| 213 |
DASHBOARD_SYSTEM = """You are an AI dashboard assistant for a book-sales analytics app.
|
| 214 |
The user asks questions or requests about their data. You have access to pre-computed
|
| 215 |
artifacts from a Python analysis pipeline.
|
| 216 |
-
|
| 217 |
AVAILABLE ARTIFACTS (only reference ones that exist):
|
| 218 |
{artifacts_json}
|
| 219 |
-
|
| 220 |
KPI SUMMARY: {kpis_json}
|
| 221 |
-
|
| 222 |
YOUR JOB:
|
| 223 |
1. Answer the user's question conversationally using the KPIs and your knowledge of the artifacts.
|
| 224 |
2. At the END of your response, output a JSON block (fenced with ```json ... ```) that tells
|
| 225 |
the dashboard which artifact to display. The JSON must have this shape:
|
| 226 |
{{"show": "figure"|"table"|"none", "scope": "python", "filename": "..."}}
|
| 227 |
-
|
| 228 |
- Use "show": "figure" to display a chart image.
|
| 229 |
- Use "show": "table" to display a CSV/JSON table.
|
| 230 |
- Use "show": "none" if no artifact is relevant.
|
| 231 |
-
|
| 232 |
RULES:
|
| 233 |
- If the user asks about sales trends or forecasting by title, show sales_trends or arima figures.
|
| 234 |
- If the user asks about sentiment, show sentiment figure or sentiment_counts table.
|
|
@@ -341,13 +336,12 @@ def ai_chat(user_msg: str, history: list):
|
|
| 341 |
if chart_name and chart_name in chart_builders:
|
| 342 |
chart_out = chart_builders[chart_name]()
|
| 343 |
elif show == "figure" and fname:
|
| 344 |
-
# Fallback: try to match filename to a chart builder
|
| 345 |
if "sales_trend" in fname:
|
| 346 |
chart_out = build_sales_chart()
|
| 347 |
elif "sentiment" in fname:
|
| 348 |
chart_out = build_sentiment_chart()
|
| 349 |
elif "arima" in fname or "forecast" in fname:
|
| 350 |
-
chart_out = build_sales_chart()
|
| 351 |
else:
|
| 352 |
chart_out = _empty_chart(f"No interactive chart for {fname}")
|
| 353 |
|
|
@@ -422,7 +416,6 @@ def _keyword_fallback(msg: str, idx: Dict, kpis: Dict) -> Tuple[str, Dict]:
|
|
| 422 |
{"show": "table", "scope": "python", "filename": "df_dashboard.csv"},
|
| 423 |
)
|
| 424 |
|
| 425 |
-
# Default
|
| 426 |
return (
|
| 427 |
f"I can show you various analyses. {kpi_text}\n\n"
|
| 428 |
"Try asking about: **sales trends**, **sentiment**, **ARIMA forecasts**, "
|
|
@@ -432,7 +425,7 @@ def _keyword_fallback(msg: str, idx: Dict, kpis: Dict) -> Tuple[str, Dict]:
|
|
| 432 |
|
| 433 |
|
| 434 |
# =========================================================
|
| 435 |
-
# KPI CARDS
|
| 436 |
# =========================================================
|
| 437 |
|
| 438 |
def render_kpi_cards() -> str:
|
|
@@ -482,7 +475,6 @@ def render_kpi_cards() -> str:
|
|
| 482 |
if isinstance(val, (int, float)) and val > 100:
|
| 483 |
val = f"{val:,.0f}"
|
| 484 |
html += card(icon, label, str(val), colour)
|
| 485 |
-
# Extra KPIs not in config
|
| 486 |
known = {k for k, *_ in kpi_config}
|
| 487 |
for key, val in kpis.items():
|
| 488 |
if key not in known:
|
|
@@ -495,7 +487,7 @@ def render_kpi_cards() -> str:
|
|
| 495 |
|
| 496 |
|
| 497 |
# =========================================================
|
| 498 |
-
# INTERACTIVE PLOTLY CHARTS
|
| 499 |
# =========================================================
|
| 500 |
|
| 501 |
CHART_PALETTE = ["#7c5cbf", "#2ec4a0", "#e8537a", "#e8a230", "#5e8fef",
|
|
@@ -653,7 +645,7 @@ with gr.Blocks(title="AIBDM 2026 Workshop App") as demo:
|
|
| 653 |
btn_all.click(run_full_pipeline, outputs=[run_log])
|
| 654 |
|
| 655 |
# ===========================================================
|
| 656 |
-
# TAB 2 -- Dashboard
|
| 657 |
# ===========================================================
|
| 658 |
with gr.Tab("Dashboard"):
|
| 659 |
kpi_html = gr.HTML(value=render_kpi_cards)
|
|
@@ -755,4 +747,12 @@ with gr.Blocks(title="AIBDM 2026 Workshop App") as demo:
|
|
| 755 |
)
|
| 756 |
|
| 757 |
|
| 758 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
DASHBOARD_SYSTEM = """You are an AI dashboard assistant for a book-sales analytics app.
|
| 214 |
The user asks questions or requests about their data. You have access to pre-computed
|
| 215 |
artifacts from a Python analysis pipeline.
|
|
|
|
| 216 |
AVAILABLE ARTIFACTS (only reference ones that exist):
|
| 217 |
{artifacts_json}
|
|
|
|
| 218 |
KPI SUMMARY: {kpis_json}
|
|
|
|
| 219 |
YOUR JOB:
|
| 220 |
1. Answer the user's question conversationally using the KPIs and your knowledge of the artifacts.
|
| 221 |
2. At the END of your response, output a JSON block (fenced with ```json ... ```) that tells
|
| 222 |
the dashboard which artifact to display. The JSON must have this shape:
|
| 223 |
{{"show": "figure"|"table"|"none", "scope": "python", "filename": "..."}}
|
|
|
|
| 224 |
- Use "show": "figure" to display a chart image.
|
| 225 |
- Use "show": "table" to display a CSV/JSON table.
|
| 226 |
- Use "show": "none" if no artifact is relevant.
|
|
|
|
| 227 |
RULES:
|
| 228 |
- If the user asks about sales trends or forecasting by title, show sales_trends or arima figures.
|
| 229 |
- If the user asks about sentiment, show sentiment figure or sentiment_counts table.
|
|
|
|
| 336 |
if chart_name and chart_name in chart_builders:
|
| 337 |
chart_out = chart_builders[chart_name]()
|
| 338 |
elif show == "figure" and fname:
|
|
|
|
| 339 |
if "sales_trend" in fname:
|
| 340 |
chart_out = build_sales_chart()
|
| 341 |
elif "sentiment" in fname:
|
| 342 |
chart_out = build_sentiment_chart()
|
| 343 |
elif "arima" in fname or "forecast" in fname:
|
| 344 |
+
chart_out = build_sales_chart()
|
| 345 |
else:
|
| 346 |
chart_out = _empty_chart(f"No interactive chart for {fname}")
|
| 347 |
|
|
|
|
| 416 |
{"show": "table", "scope": "python", "filename": "df_dashboard.csv"},
|
| 417 |
)
|
| 418 |
|
|
|
|
| 419 |
return (
|
| 420 |
f"I can show you various analyses. {kpi_text}\n\n"
|
| 421 |
"Try asking about: **sales trends**, **sentiment**, **ARIMA forecasts**, "
|
|
|
|
| 425 |
|
| 426 |
|
| 427 |
# =========================================================
|
| 428 |
+
# KPI CARDS
|
| 429 |
# =========================================================
|
| 430 |
|
| 431 |
def render_kpi_cards() -> str:
|
|
|
|
| 475 |
if isinstance(val, (int, float)) and val > 100:
|
| 476 |
val = f"{val:,.0f}"
|
| 477 |
html += card(icon, label, str(val), colour)
|
|
|
|
| 478 |
known = {k for k, *_ in kpi_config}
|
| 479 |
for key, val in kpis.items():
|
| 480 |
if key not in known:
|
|
|
|
| 487 |
|
| 488 |
|
| 489 |
# =========================================================
|
| 490 |
+
# INTERACTIVE PLOTLY CHARTS
|
| 491 |
# =========================================================
|
| 492 |
|
| 493 |
CHART_PALETTE = ["#7c5cbf", "#2ec4a0", "#e8537a", "#e8a230", "#5e8fef",
|
|
|
|
| 645 |
btn_all.click(run_full_pipeline, outputs=[run_log])
|
| 646 |
|
| 647 |
# ===========================================================
|
| 648 |
+
# TAB 2 -- Dashboard
|
| 649 |
# ===========================================================
|
| 650 |
with gr.Tab("Dashboard"):
|
| 651 |
kpi_html = gr.HTML(value=render_kpi_cards)
|
|
|
|
| 747 |
)
|
| 748 |
|
| 749 |
|
| 750 |
+
# =========================================================
|
| 751 |
+
# LAUNCH — server_name="0.0.0.0" is required on HF Spaces
|
| 752 |
+
# =========================================================
|
| 753 |
+
demo.launch(
|
| 754 |
+
css=load_css(),
|
| 755 |
+
allowed_paths=[str(BASE_DIR)],
|
| 756 |
+
server_name="0.0.0.0",
|
| 757 |
+
server_port=7860,
|
| 758 |
+
)
|