# app.py — BizIntel AI Ultra v2 # Features: CSV upload, SQL DB fetch, interactive Plotly, Gemini 1.5 Pro, # optional EDA, download buttons. import os import tempfile from io import StringIO, BytesIO 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 # returns text & PNG; we’ll also grab df from tools.visuals import ( histogram_tool, scatter_matrix_tool, corr_heatmap_tool, ) from db_connector import fetch_data_from_db, list_tables, SUPPORTED_ENGINES # ────────────────────────────────────────────────────────────── # 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"}, ) # ────────────────────────────────────────────────────────────── # Streamlit page # ────────────────────────────────────────────────────────────── 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() # ────────────────────────────────────────────────────────────── # 1. CHOOSE DATA SOURCE # ────────────────────────────────────────────────────────────── data_source = st.radio("Select data source", ["Upload CSV", "Connect to SQL Database"]) csv_path: str | None = None if data_source == "Upload CSV": csv_file = st.file_uploader("Upload CSV (≤ 200 MB)", type=["csv"]) if csv_file: csv_path = os.path.join(TEMP_DIR, csv_file.name) with open(csv_path, "wb") as f: f.write(csv_file.read()) st.success("CSV saved ✅") elif data_source == "Connect to SQL Database": engine = st.selectbox("DB engine", SUPPORTED_ENGINES) conn_str = st.text_input("SQLAlchemy connection string") if conn_str: try: tables = list_tables(conn_str) except Exception as e: st.error(f"Connection failed: {e}") st.stop() table = st.selectbox("Select table", tables) if st.button("Fetch table"): csv_path = fetch_data_from_db(conn_str, table) st.success(f"Fetched ‘{table}’ into CSV ✅") # Stop if we still don’t have a CSV if csv_path is None: st.stop() # Offer original CSV download with open(csv_path, "rb") as f: st.download_button("⬇️ Download original CSV", f, file_name=os.path.basename(csv_path)) # ────────────────────────────────────────────────────────────── # 2. 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) # ────────────────────────────────────────────────────────────── # 3. RUN LOCAL TOOLS # ────────────────────────────────────────────────────────────── with st.spinner("Parsing CSV…"): 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) # PNG created # Also capture forecast df from statsmodels if you return it (optional) try: forecast_df = pd.read_csv(StringIO(forecast_text)) except Exception: forecast_df = None # Forecast plot preview if os.path.exists("forecast_plot.png"): st.image("forecast_plot.png", caption="Sales Forecast", use_column_width=True) # Download forecast CSV if df exists if forecast_df is not None and not forecast_df.empty: buf = StringIO() forecast_df.to_csv(buf, index=False) st.download_button("⬇️ Download Forecast CSV", buf.getvalue(), file_name="forecast.csv") # ────────────────────────────────────────────────────────────── # 4. GEMINI STRATEGY # ────────────────────────────────────────────────────────────── prompt = ( f"You are **BizIntel Strategist AI**.\n\n" "### CSV Summary\n" f"```\n{summary_text}\n```\n\n" "### Forecast Output\n" f"```\n{forecast_text}\n```\n\n" "Return **Markdown** with:\n" "1. Five key insights\n" "2. Three actionable strategies (with expected impact)\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) # Download strategy as Markdown st.download_button("⬇️ Download Strategy (.md)", strategy_md, file_name="strategy.md") # ────────────────────────────────────────────────────────────── # 5. OPTIONAL EXPLORATORY VISUALS # ────────────────────────────────────────────────────────────── st.markdown("---") st.subheader("🔍 Optional Exploratory Visuals") num_cols = df_preview.select_dtypes("number").columns if st.checkbox("Histogram"): col = st.selectbox("Variable", num_cols, key="hist") st.plotly_chart(histogram_tool(csv_path, col), use_container_width=True) if st.checkbox("Scatter‑matrix"): cols = st.multiselect("Choose up to 5 columns", num_cols, default=num_cols[:3]) if cols: st.plotly_chart(scatter_matrix_tool(csv_path, cols), use_container_width=True) if st.checkbox("Correlation heat‑map"): st.plotly_chart(corr_heatmap_tool(csv_path), use_container_width=True) # ────────────────────────────────────────────────────────────── # 6. FULL SUMMARY # ────────────────────────────────────────────────────────────── st.markdown("---") st.subheader("📑 CSV Summary (stats)") st.text(summary_text)