# app.py — BizIntel AI Ultra (CSV, Excel, DB; Plotly, Gemini 1.5 Pro) import os import tempfile from io import StringIO from typing import Literal import pandas as pd import streamlit as st import google.generativeai as genai import plotly.graph_objects as go from tools.csv_parser import parse_csv_tool from tools.plot_generator import plot_sales_tool from tools.forecaster import forecast_tool from tools.visuals import histogram_tool, scatter_matrix_tool, corr_heatmap_tool from db_connector import fetch_data_from_db, list_tables, SUPPORTED_ENGINES # ────────────────────────────────────────────────────────────── # 1. GEMINI 1.5‑PRO # ────────────────────────────────────────────────────────────── genai.configure(api_key=os.getenv("GEMINI_APIKEY")) gemini = genai.GenerativeModel( "gemini-1.5-pro-latest", generation_config={"temperature": 0.7, "top_p": 0.9, "response_mime_type": "text/plain"}, ) # ────────────────────────────────────────────────────────────── # 2. PAGE SETUP # ────────────────────────────────────────────────────────────── st.set_page_config(page_title="BizIntel AI Ultra", layout="wide") st.title("📊 BizIntel AI Ultra – Advanced Analytics + Gemini 1.5 Pro") TEMP_DIR = tempfile.gettempdir() # ────────────────────────────────────────────────────────────── # 3. DATA SOURCE (CSV, Excel, or DB) # ────────────────────────────────────────────────────────────── source = st.radio("Select data source", ["Upload CSV / Excel", "Connect to SQL Database"]) csv_path: str | None = None file_type: Literal["csv", "excel"] | None = None if source == "Upload CSV / Excel": up = st.file_uploader("Upload CSV or Excel (≤ 500 MB)", type=["csv", "xlsx", "xls"]) if up: suffix = up.name.split(".")[-1].lower() temp_path = os.path.join(TEMP_DIR, up.name) with open(temp_path, "wb") as f: f.write(up.read()) if suffix == "csv": csv_path = temp_path file_type = "csv" else: # Excel → convert sheet0 to CSV file_type = "excel" try: df_excel = pd.read_excel(temp_path, sheet_name=0) # loads first sheet csv_path = os.path.splitext(temp_path)[0] + ".csv" df_excel.to_csv(csv_path, index=False) except Exception as e: st.error(f"Excel parsing failed: {e}") st.stop() st.success(f"{up.name} saved ✅") else: # SQL DB engine = st.selectbox("DB engine", SUPPORTED_ENGINES) conn = st.text_input("SQLAlchemy connection string") if conn: try: tbls = list_tables(conn) tbl = st.selectbox("Table", tbls) if st.button("Fetch table"): csv_path = fetch_data_from_db(conn, tbl) file_type = "csv" st.success(f"Fetched **{tbl}** as CSV ✅") except Exception as e: st.error(f"Connection failed: {e}") st.stop() if csv_path is None: st.stop() # Download working CSV with open(csv_path, "rb") as f: st.download_button("⬇️ Download working CSV", f, file_name=os.path.basename(csv_path)) # ────────────────────────────────────────────────────────────── # 4. PREVIEW & DATE COL # ────────────────────────────────────────────────────────────── df_preview = pd.read_csv(csv_path, nrows=5) st.dataframe(df_preview) date_col = st.selectbox("Select date/time column for forecasting", df_preview.columns) # ────────────────────────────────────────────────────────────── # 5. LOCAL TOOLS # ────────────────────────────────────────────────────────────── with st.spinner("Parsing dataset…"): summary_text = parse_csv_tool(csv_path) with st.spinner("📈 Generating sales trend…"): sales_fig = plot_sales_tool(csv_path, date_col=date_col) if isinstance(sales_fig, go.Figure): st.plotly_chart(sales_fig, use_container_width=True) else: st.warning(sales_fig) with st.spinner("🔮 Forecasting…"): forecast_text = forecast_tool(csv_path, date_col=date_col) forecast_png = "forecast_plot.png" if os.path.exists("forecast_plot.png") else None if forecast_png: st.image(forecast_png, caption="Sales Forecast", use_column_width=True) # ────────────────────────────────────────────────────────────── # 6. GEMINI STRATEGY # ────────────────────────────────────────────────────────────── prompt = ( f"You are **BizIntel Strategist AI**.\n\n" f"### CSV Summary\n```\n{summary_text}\n```\n\n" f"### Forecast Output\n```\n{forecast_text}\n```\n\n" "Return **Markdown** with:\n" "1. Five key insights\n" "2. Three actionable strategies\n" "3. Risk factors or anomalies\n" "4. Suggested additional visuals\n" ) st.subheader("🚀 Strategy Recommendations (Gemini 1.5 Pro)") with st.spinner("Generating insights…"): strategy_md = gemini.generate_content(prompt).text st.markdown(strategy_md) st.download_button("⬇️ Download Strategy (.md)", strategy_md, file_name="strategy.md") # ────────────────────────────────────────────────────────────── # 7. KPI CARDS + EXPANDER # ────────────────────────────────────────────────────────────── full_df = pd.read_csv(csv_path, low_memory=False) total_rows = len(full_df) num_cols = len(full_df.columns) missing_pct = full_df.isna().mean().mean() * 100 st.markdown("---") st.subheader("📑 Dataset Overview") c1, c2, c3 = st.columns(3) c1.metric("Rows", f"{total_rows:,}") c2.metric("Columns", str(num_cols)) c3.metric("Missing %", f"{missing_pct:.1f}%") with st.expander("🔎 Detailed descriptive statistics"): stats_df = full_df.describe().T.reset_index().rename(columns={"index": "Feature"}) st.dataframe( stats_df.style.format(precision=2).background_gradient(cmap="Blues"), use_container_width=True, ) # ────────────────────────────────────────────────────────────── # 8. OPTIONAL EXPLORATORY VISUALS # ────────────────────────────────────────────────────────────── st.markdown("---") st.subheader("🔍 Optional Exploratory Visuals") num_cols = df_preview.select_dtypes("number").columns if st.checkbox("Histogram"): hcol = st.selectbox("Variable", num_cols, key="hist") st.plotly_chart(histogram_tool(csv_path, hcol), use_container_width=True) if st.checkbox("Scatter‑matrix"): sel = st.multiselect("Choose columns", num_cols, default=num_cols[:3]) if sel: st.plotly_chart(scatter_matrix_tool(csv_path, sel), use_container_width=True) if st.checkbox("Correlation heat‑map"): st.plotly_chart(corr_heatmap_tool(csv_path), use_container_width=True)