BizIntel_AI / app.py
mgbam's picture
Update app.py
773f0cf verified
raw
history blame
8.08 kB
# 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)