Spaces:
Sleeping
Sleeping
# 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) | |