mgbam commited on
Commit
9414ba2
ยท
verified ยท
1 Parent(s): 3651f7b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -53
app.py CHANGED
@@ -1,8 +1,7 @@
1
- # app.py โ€” BizIntelย AIย Ultra (CSV, Excel, DB; Plotly, Geminiโ€ฏ1.5โ€ฏPro)
2
 
3
  import os
4
  import tempfile
5
- from io import StringIO
6
  from typing import Literal
7
 
8
  import pandas as pd
@@ -10,14 +9,14 @@ import streamlit as st
10
  import google.generativeai as genai
11
  import plotly.graph_objects as go
12
 
13
- from tools.csv_parser import parse_csv_tool
14
- from tools.plot_generator import plot_sales_tool
15
- from tools.forecaster import forecast_tool
16
- from tools.visuals import histogram_tool, scatter_matrix_tool, corr_heatmap_tool
17
- from db_connector import fetch_data_from_db, list_tables, SUPPORTED_ENGINES
18
 
19
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
20
- # 1. GEMINI 1.5โ€‘PRO
21
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
22
  genai.configure(api_key=os.getenv("GEMINI_APIKEY"))
23
  gemini = genai.GenerativeModel(
@@ -26,7 +25,7 @@ gemini = genai.GenerativeModel(
26
  )
27
 
28
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
29
- # 2. PAGE SETUP
30
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
31
  st.set_page_config(page_title="BizIntelย AIย Ultra", layout="wide")
32
  st.title("๐Ÿ“Š BizIntelย AIย Ultraย โ€“ Advanced Analytics + Geminiย 1.5ย Pro")
@@ -36,28 +35,25 @@ TEMP_DIR = tempfile.gettempdir()
36
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
37
  # 3. DATA SOURCE (CSV, Excel, or DB)
38
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
39
- source = st.radio("Select data source", ["Upload CSV / Excel", "Connect to SQL Database"])
40
-
41
  csv_path: str | None = None
42
- file_type: Literal["csv", "excel"] | None = None
43
 
44
- if source == "Upload CSV / Excel":
45
  up = st.file_uploader("Upload CSV or Excel (โ‰คโ€ฏ500โ€ฏMB)", type=["csv", "xlsx", "xls"])
46
  if up:
47
- suffix = up.name.split(".")[-1].lower()
48
  temp_path = os.path.join(TEMP_DIR, up.name)
49
  with open(temp_path, "wb") as f:
50
  f.write(up.read())
51
 
52
- if suffix == "csv":
53
- csv_path = temp_path
54
- file_type = "csv"
55
- else: # Excel โ†’ convert sheet0 to CSV
56
- file_type = "excel"
57
  try:
58
- df_excel = pd.read_excel(temp_path, sheet_name=0) # loads first sheet
59
  csv_path = os.path.splitext(temp_path)[0] + ".csv"
60
- df_excel.to_csv(csv_path, index=False)
 
61
  except Exception as e:
62
  st.error(f"Excel parsing failed: {e}")
63
  st.stop()
@@ -65,14 +61,14 @@ if source == "Upload CSV / Excel":
65
 
66
  else: # SQL DB
67
  engine = st.selectbox("DB engine", SUPPORTED_ENGINES)
68
- conn = st.text_input("SQLAlchemy connection string")
69
  if conn:
70
  try:
71
  tbls = list_tables(conn)
72
- tbl = st.selectbox("Table", tbls)
73
  if st.button("Fetch table"):
74
  csv_path = fetch_data_from_db(conn, tbl)
75
- file_type = "csv"
76
  st.success(f"Fetched **{tbl}** as CSV โœ…")
77
  except Exception as e:
78
  st.error(f"Connection failed: {e}")
@@ -81,47 +77,49 @@ else: # SQL DB
81
  if csv_path is None:
82
  st.stop()
83
 
84
- # Download working CSV
85
  with open(csv_path, "rb") as f:
86
  st.download_button("โฌ‡๏ธย Download working CSV", f, file_name=os.path.basename(csv_path))
87
 
88
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
89
- # 4. PREVIEW & DATE COL
90
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
91
- df_preview = pd.read_csv(csv_path, nrows=5)
92
- st.dataframe(df_preview)
93
- date_col = st.selectbox("Select date/time column for forecasting", df_preview.columns)
 
 
 
94
 
95
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
96
- # 5. LOCAL TOOLS
97
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
98
  with st.spinner("Parsing datasetโ€ฆ"):
99
  summary_text = parse_csv_tool(csv_path)
100
 
101
- with st.spinner("๐Ÿ“ˆ Generating sales trendโ€ฆ"):
102
- sales_fig = plot_sales_tool(csv_path, date_col=date_col)
103
- if isinstance(sales_fig, go.Figure):
104
- st.plotly_chart(sales_fig, use_container_width=True)
105
  else:
106
- st.warning(sales_fig)
107
 
108
  with st.spinner("๐Ÿ”ฎ Forecastingโ€ฆ"):
109
- forecast_text = forecast_tool(csv_path, date_col=date_col)
110
- forecast_png = "forecast_plot.png" if os.path.exists("forecast_plot.png") else None
111
 
112
  if forecast_png:
113
- st.image(forecast_png, caption="Sales Forecast", use_column_width=True)
114
 
115
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
116
- # 6. GEMINI STRATEGY
117
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
118
  prompt = (
119
  f"You are **BizIntel Strategist AI**.\n\n"
120
- f"### CSV Summary\n```\n{summary_text}\n```\n\n"
121
- f"### Forecast Output\n```\n{forecast_text}\n```\n\n"
122
- "Return **Markdown** with:\n"
123
- "1. Five key insights\n"
124
- "2. Three actionable strategies\n"
125
  "3. Risk factors or anomalies\n"
126
  "4. Suggested additional visuals\n"
127
  )
@@ -133,9 +131,9 @@ st.markdown(strategy_md)
133
  st.download_button("โฌ‡๏ธย Download Strategy (.md)", strategy_md, file_name="strategy.md")
134
 
135
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
136
- # 7. KPI CARDS + EXPANDER
137
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
138
- full_df = pd.read_csv(csv_path, low_memory=False)
139
  total_rows = len(full_df)
140
  num_cols = len(full_df.columns)
141
  missing_pct = full_df.isna().mean().mean() * 100
@@ -143,8 +141,8 @@ missing_pct = full_df.isna().mean().mean() * 100
143
  st.markdown("---")
144
  st.subheader("๐Ÿ“‘ Dataset Overview")
145
  c1, c2, c3 = st.columns(3)
146
- c1.metric("Rows", f"{total_rows:,}")
147
- c2.metric("Columns", str(num_cols))
148
  c3.metric("Missingย %", f"{missing_pct:.1f}%")
149
 
150
  with st.expander("๐Ÿ”Žย Detailed descriptive statistics"):
@@ -160,14 +158,12 @@ with st.expander("๐Ÿ”Žย Detailed descriptive statistics"):
160
  st.markdown("---")
161
  st.subheader("๐Ÿ” Optional Exploratory Visuals")
162
 
163
- num_cols = df_preview.select_dtypes("number").columns
164
-
165
  if st.checkbox("Histogram"):
166
- hcol = st.selectbox("Variable", num_cols, key="hist")
167
- st.plotly_chart(histogram_tool(csv_path, hcol), use_container_width=True)
168
 
169
  if st.checkbox("Scatterโ€‘matrix"):
170
- sel = st.multiselect("Choose columns", num_cols, default=num_cols[:3])
171
  if sel:
172
  st.plotly_chart(scatter_matrix_tool(csv_path, sel), use_container_width=True)
173
 
 
1
+ # app.py โ€” BizIntelย AIย Ultraย (Any metric, CSV/Excel/DB, Plotly, Geminiย 1.5โ€ฏPro)
2
 
3
  import os
4
  import tempfile
 
5
  from typing import Literal
6
 
7
  import pandas as pd
 
9
  import google.generativeai as genai
10
  import plotly.graph_objects as go
11
 
12
+ from tools.csv_parser import parse_csv_tool
13
+ from tools.plot_generator import plot_metric_tool # NEW generic
14
+ from tools.forecaster import forecast_metric_tool # NEW generic
15
+ from tools.visuals import histogram_tool, scatter_matrix_tool, corr_heatmap_tool
16
+ from db_connector import fetch_data_from_db, list_tables, SUPPORTED_ENGINES
17
 
18
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
19
+ # 1. GEMINI CONFIG
20
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
21
  genai.configure(api_key=os.getenv("GEMINI_APIKEY"))
22
  gemini = genai.GenerativeModel(
 
25
  )
26
 
27
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
28
+ # 2. PAGE CONFIG
29
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
30
  st.set_page_config(page_title="BizIntelย AIย Ultra", layout="wide")
31
  st.title("๐Ÿ“Š BizIntelย AIย Ultraย โ€“ Advanced Analytics + Geminiย 1.5ย Pro")
 
35
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
36
  # 3. DATA SOURCE (CSV, Excel, or DB)
37
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
38
+ src = st.radio("Select data source", ["Upload CSV / Excel", "Connect to SQL Database"])
 
39
  csv_path: str | None = None
40
+ file_kind: Literal["csv", "excel"] | None = None
41
 
42
+ if src == "Upload CSV / Excel":
43
  up = st.file_uploader("Upload CSV or Excel (โ‰คโ€ฏ500โ€ฏMB)", type=["csv", "xlsx", "xls"])
44
  if up:
 
45
  temp_path = os.path.join(TEMP_DIR, up.name)
46
  with open(temp_path, "wb") as f:
47
  f.write(up.read())
48
 
49
+ if up.name.lower().endswith("csv"):
50
+ csv_path, file_kind = temp_path, "csv"
51
+ else: # Excel โ†’ convert first sheet to CSV
 
 
52
  try:
53
+ df_xl = pd.read_excel(temp_path, sheet_name=0)
54
  csv_path = os.path.splitext(temp_path)[0] + ".csv"
55
+ df_xl.to_csv(csv_path, index=False)
56
+ file_kind = "excel"
57
  except Exception as e:
58
  st.error(f"Excel parsing failed: {e}")
59
  st.stop()
 
61
 
62
  else: # SQL DB
63
  engine = st.selectbox("DB engine", SUPPORTED_ENGINES)
64
+ conn = st.text_input("SQLAlchemy connection string")
65
  if conn:
66
  try:
67
  tbls = list_tables(conn)
68
+ tbl = st.selectbox("Table", tbls)
69
  if st.button("Fetch table"):
70
  csv_path = fetch_data_from_db(conn, tbl)
71
+ file_kind = "csv"
72
  st.success(f"Fetched **{tbl}** as CSV โœ…")
73
  except Exception as e:
74
  st.error(f"Connection failed: {e}")
 
77
  if csv_path is None:
78
  st.stop()
79
 
 
80
  with open(csv_path, "rb") as f:
81
  st.download_button("โฌ‡๏ธย Download working CSV", f, file_name=os.path.basename(csv_path))
82
 
83
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
84
+ # 4. COLUMN PICKERS
85
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
86
+ df_head = pd.read_csv(csv_path, nrows=5)
87
+ st.dataframe(df_head)
88
+
89
+ date_col = st.selectbox("Select date/time column", df_head.columns)
90
+ numeric_cols = df_head.select_dtypes("number").columns
91
+ metric_col = st.selectbox("Select numeric metric column", numeric_cols)
92
 
93
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
94
+ # 5. LOCAL TOOLS (TREND + FORECAST)
95
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
96
  with st.spinner("Parsing datasetโ€ฆ"):
97
  summary_text = parse_csv_tool(csv_path)
98
 
99
+ with st.spinner("๐Ÿ“ˆ Building trend chartโ€ฆ"):
100
+ trend_fig = plot_metric_tool(csv_path, date_col, metric_col)
101
+ if isinstance(trend_fig, go.Figure):
102
+ st.plotly_chart(trend_fig, use_container_width=True)
103
  else:
104
+ st.warning(trend_fig)
105
 
106
  with st.spinner("๐Ÿ”ฎ Forecastingโ€ฆ"):
107
+ forecast_text = forecast_metric_tool(csv_path, date_col, metric_col)
108
+ forecast_png = "forecast_plot.png" if os.path.exists("forecast_plot.png") else None
109
 
110
  if forecast_png:
111
+ st.image(forecast_png, caption=f"{metric_col} Forecast", use_column_width=True)
112
 
113
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
114
+ # 6. GEMINI INSIGHTS
115
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
116
  prompt = (
117
  f"You are **BizIntel Strategist AI**.\n\n"
118
+ f"### Dataset Summary\n```\n{summary_text}\n```\n\n"
119
+ f"### {metric_col} Forecast\n```\n{forecast_text}\n```\n\n"
120
+ "Deliver **Markdown** with:\n"
121
+ f"1. Five key insights focused on **{metric_col}**\n"
122
+ "2. Three actionable strategies (impactโ€‘oriented)\n"
123
  "3. Risk factors or anomalies\n"
124
  "4. Suggested additional visuals\n"
125
  )
 
131
  st.download_button("โฌ‡๏ธย Download Strategy (.md)", strategy_md, file_name="strategy.md")
132
 
133
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
134
+ # 7. KPI CARDS + STAT EXPANDER
135
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
136
+ full_df = pd.read_csv(csv_path, low_memory=False)
137
  total_rows = len(full_df)
138
  num_cols = len(full_df.columns)
139
  missing_pct = full_df.isna().mean().mean() * 100
 
141
  st.markdown("---")
142
  st.subheader("๐Ÿ“‘ Dataset Overview")
143
  c1, c2, c3 = st.columns(3)
144
+ c1.metric("Rows", f"{total_rows:,}")
145
+ c2.metric("Columns", str(num_cols))
146
  c3.metric("Missingย %", f"{missing_pct:.1f}%")
147
 
148
  with st.expander("๐Ÿ”Žย Detailed descriptive statistics"):
 
158
  st.markdown("---")
159
  st.subheader("๐Ÿ” Optional Exploratory Visuals")
160
 
 
 
161
  if st.checkbox("Histogram"):
162
+ hist_col = st.selectbox("Variable", numeric_cols, key="hist")
163
+ st.plotly_chart(histogram_tool(csv_path, hist_col), use_container_width=True)
164
 
165
  if st.checkbox("Scatterโ€‘matrix"):
166
+ sel = st.multiselect("Choose columns", numeric_cols, default=numeric_cols[:3])
167
  if sel:
168
  st.plotly_chart(scatter_matrix_tool(csv_path, sel), use_container_width=True)
169