"""Smart Analytics Copilot - Complete Version With Export, OpenAI, Save/Load, Chart Customization, Power BI Export""" import streamlit as st import pandas as pd import os from datetime import datetime from dotenv import load_dotenv #Load environment variables load_dotenv() from data_processor import DataProcessor from analyzer import Analyzer from insight_generator import InsightGenerator from dashboard import DashboardGenerator from query_engine import QueryEngine from export_utils import ExportUtils from session_manager import SessionManager from chart_customizer import ChartCustomizer #Page config st.set_page_config( page_title="Smart Analytics Copilot", page_icon="🚀", layout="wide", initial_sidebar_state="expanded" ) # ============ DARK THEME CSS ============ st.markdown(""" """, unsafe_allow_html=True) # Initialize session state if 'data_loaded' not in st.session_state: st.session_state.data_loaded = False if 'df' not in st.session_state: st.session_state.df = None if 'schema' not in st.session_state: st.session_state.schema = None if 'analysis' not in st.session_state: st.session_state.analysis = None if 'insights' not in st.session_state: st.session_state.insights = None if 'charts' not in st.session_state: st.session_state.charts = None if 'use_openai' not in st.session_state: st.session_state.use_openai = False # Initialize managers session_mgr = SessionManager() def main(): st.markdown('
🚀 Smart Analytics Copilot
', unsafe_allow_html=True) st.caption("✨ Upload any CSV/JSON - AI analyzes, visualizes, and answers questions") st.markdown("---") # Sidebar with st.sidebar: st.markdown("### 📁 Data Source") # Data source selection source = st.radio("Choose data source:", ["📤 Upload File", "💾 Load Saved Session"]) if source == "📤 Upload File": uploaded_file = st.file_uploader("Choose CSV or JSON", type=['csv', 'json']) if uploaded_file and not st.session_state.data_loaded: with st.spinner("🔄 Processing your data..."): process_data(uploaded_file) else: # Load saved sessions sessions = session_mgr.list_sessions() if sessions: session_names = [s['name'] for s in sessions] selected_session = st.selectbox("Select saved session:", session_names) if st.button("📂 Load Session"): with st.spinner("Loading..."): load_session(selected_session) else: st.info("No saved sessions found") st.markdown("---") # Settings with st.expander("⚙️ Settings"): st.session_state.use_openai = st.checkbox("Use OpenAI (better insights)", value=st.session_state.use_openai) if st.session_state.use_openai: api_key = st.text_input("OpenAI API Key:", type="password") if api_key: os.environ['OPENAI_API_KEY'] = api_key st.success("API Key set!") st.markdown("---") # Export section (only if data loaded) if st.session_state.data_loaded: st.markdown("### 💾 Export Options") export_utils = ExportUtils(st.session_state.df) export_format = st.selectbox("Export format:", ["CSV", "Excel", "JSON", "Power BI CSV", "Power BI ZIP (Complete)"]) if st.button("📥 Download"): if export_format == "CSV": data = export_utils.to_csv() mime = "text/csv" ext = "csv" elif export_format == "Excel": data = export_utils.to_excel() mime = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ext = "xlsx" elif export_format == "JSON": data = export_utils.to_json() mime = "application/json" ext = "json" elif export_format == "Power BI CSV": data = export_utils.to_powerbi_ready() mime = "text/csv" ext = "csv" else: # Power BI ZIP (Complete) data = export_utils.to_powerbi_zip() mime = "application/zip" ext = "zip" st.download_button( label="✅ Click to Download", data=data, file_name=f"export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.{ext}", mime=mime ) # Save session button st.markdown("---") if st.button("💾 Save Current Session"): name, path = session_mgr.save_session(st.session_state.df, st.session_state.schema) st.success(f"✅ Session saved as: {name}") # Main content if st.session_state.data_loaded: tab1, tab2, tab3, tab4, tab5 = st.tabs([ "📊 Dashboard", "💡 AI Insights", "🎨 Custom Charts", "🔍 Query", "📋 Data" ]) with tab1: show_dashboard() with tab2: show_insights() with tab3: show_chart_customizer() with tab4: show_query_interface() with tab5: show_data_preview() else: show_welcome() def process_data(uploaded_file): """Process uploaded data""" try: processor = DataProcessor() st.session_state.df = processor.load_from_upload(uploaded_file) st.session_state.df = processor.preprocess() st.session_state.schema = processor.detect_schema() analyzer = Analyzer(st.session_state.df, st.session_state.schema) st.session_state.analysis = analyzer.run_full_analysis() # Use OpenAI if enabled api_key = os.environ.get('OPENAI_API_KEY') insight_gen = InsightGenerator(use_openai=st.session_state.use_openai, api_key=api_key) st.session_state.insights = insight_gen.generate_insights( st.session_state.df, st.session_state.schema, st.session_state.analysis ) dashboard_gen = DashboardGenerator(st.session_state.df, st.session_state.schema) st.session_state.charts = dashboard_gen.generate_all_charts() st.session_state.data_loaded = True st.success(f"✅ Successfully loaded {len(st.session_state.df):,} rows with {len(st.session_state.df.columns)} columns") st.balloons() st.rerun() except Exception as e: st.error(f"Error: {e}") def load_session(session_name): """Load saved session and regenerate insights""" session = session_mgr.load_session(session_name) if session: st.session_state.df = session['df'] st.session_state.schema = session['schema'] # Regenerate analysis and insights for loaded session with st.spinner("🔄 Regenerating analysis..."): analyzer = Analyzer(st.session_state.df, st.session_state.schema) st.session_state.analysis = analyzer.run_full_analysis() # Regenerate insights api_key = os.environ.get('OPENAI_API_KEY') insight_gen = InsightGenerator(use_openai=st.session_state.use_openai, api_key=api_key) st.session_state.insights = insight_gen.generate_insights( st.session_state.df, st.session_state.schema, st.session_state.analysis ) # Regenerate charts dashboard_gen = DashboardGenerator(st.session_state.df, st.session_state.schema) st.session_state.charts = dashboard_gen.generate_all_charts() st.session_state.data_loaded = True st.success(f"✅ Loaded session: {session_name}") st.rerun() else: st.error("Failed to load session") def show_dashboard(): """Display dashboard""" st.markdown("### 📈 Key Metrics") st.markdown("---") # Check if data exists if st.session_state.df is None: st.warning("No data loaded. Please upload a file first.") return # Display metrics if st.session_state.schema['numeric']: cols = st.columns(min(4, len(st.session_state.schema['numeric']))) for idx, col in enumerate(st.session_state.schema['numeric'][:4]): with cols[idx]: total = st.session_state.df[col].sum() avg = st.session_state.df[col].mean() st.metric( label=f"💰 {col.upper()}", value=f"{total:,.0f}", delta=f"Avg: {avg:,.0f}" ) st.markdown("---") st.markdown("### 📊 Visualizations") if st.session_state.charts: for chart in st.session_state.charts[:4]: st.plotly_chart(chart['figure'], use_container_width=True) else: st.info("No charts available. Try uploading data first.") st.markdown("---") st.markdown("### 📋 Summary Statistics") if st.session_state.schema['numeric']: summary = st.session_state.df[st.session_state.schema['numeric']].describe() st.dataframe(summary, use_container_width=True) def show_insights(): """Display AI insights""" st.markdown("### 🧠 AI-Powered Insights") st.markdown("Here's what we discovered in your data:") st.markdown("---") # Check if insights exist if st.session_state.insights is None: st.info("💡 Insights will appear after data is analyzed.") return for insight in st.session_state.insights: if "Dataset" in insight: st.info(f"📊 {insight}") elif "correlation" in insight.lower(): st.success(f"✅ {insight}") elif "skewed" in insight.lower(): st.warning(f"📈 {insight}") elif "Recommendation" in insight: st.info(f"💡 {insight}") else: st.markdown(f"• {insight}") # Power BI template section st.markdown("---") with st.expander("📊 Power BI Resources"): export_utils = ExportUtils(st.session_state.df) col1, col2 = st.columns(2) with col1: # Show DAX template template = export_utils.get_powerbi_template() st.code(template, language="dax") st.download_button( label="📥 Download DAX Template", data=template, file_name="powerbi_measures.dax", mime="text/plain" ) with col2: # Show instructions instructions = """ **Power BI Import Steps:** 1. **Export Data**: Use sidebar to export as "Power BI CSV" 2. **Open Power BI Desktop** 3. **Get Data** → **Text/CSV** 4. **Select your exported CSV** 5. **Click Load** 6. **Copy DAX measures** from above 7. **Create visuals** using the measures """ st.info(instructions) def show_chart_customizer(): """Show chart customization interface""" st.markdown("### 🎨 Custom Chart Builder") st.markdown("Create your own custom visualizations") st.markdown("---") customizer = ChartCustomizer(st.session_state.df) available_charts = customizer.get_available_charts() col1, col2, col3 = st.columns([1, 1, 1]) with col1: chart_type = st.selectbox("Chart Type:", available_charts) with col2: # Get appropriate columns if 'Histogram' in chart_type or 'Box' in chart_type: columns = st.session_state.schema['numeric'] if not columns: columns = list(st.session_state.df.select_dtypes(include=['number']).columns) elif 'Pie' in chart_type or 'Bar' in chart_type: columns = st.session_state.schema['categorical'] if not columns: columns = list(st.session_state.df.select_dtypes(include=['object']).columns) else: columns = list(st.session_state.df.columns) if columns: x_col = st.selectbox("X-Axis / Category:", columns) else: x_col = None st.warning("No suitable columns found") with col3: # For charts that need Y-axis if any(t in chart_type for t in ['Line', 'Scatter', 'Bar']) and 'Histogram' not in chart_type: y_cols = ['None'] + st.session_state.schema['numeric'] y_col = st.selectbox("Y-Axis / Value:", y_cols) y_col = None if y_col == 'None' else y_col else: y_col = None # Color column (optional) color_cols = ['None'] + st.session_state.schema['categorical'] color_col = st.selectbox("Color By (optional):", color_cols) color_col = None if color_col == 'None' else color_col # Title title = st.text_input("Chart Title:", value=f"{chart_type} of {x_col if x_col else 'data'}") if st.button("🎨 Generate Chart", use_container_width=True): if x_col: with st.spinner("Creating chart..."): fig = customizer.create_chart(chart_type, x_col, y_col, color_col, title) if fig: st.plotly_chart(fig, use_container_width=True) # Download chart button try: st.download_button( label="📸 Download as PNG", data=fig.to_image(format="png"), file_name="custom_chart.png", mime="image/png" ) except: st.info("💡 Install kaleido for PNG export: `pip install kaleido`") else: st.error("Could not create chart. Try different settings.") else: st.error("Please select a column for X-Axis") def show_query_interface(): """Natural language query interface""" st.markdown("### 💬 Natural Language Query") st.markdown("Ask any question about your data in plain English:") st.markdown("---") query_engine = QueryEngine(st.session_state.df, st.session_state.schema) # Example questions with st.expander("🔍 View Example Questions"): if st.session_state.schema['numeric']: example_col = st.session_state.schema['numeric'][0] st.markdown(f"• 'Statistics {example_col}'") st.markdown(f"• 'Total {example_col}'") st.markdown(f"• 'Average {example_col}'") if st.session_state.schema['categorical'] and st.session_state.schema['numeric']: st.markdown(f"• 'Top 5 {st.session_state.schema['categorical'][0]} by {st.session_state.schema['numeric'][0]}'") st.markdown("• 'Summary statistics'") st.markdown("• 'Show me the data'") st.markdown("---") question = st.text_input("Ask a question:", placeholder="e.g., What is the average of time_in_hospital?") if question: with st.spinner("🤔 Analyzing your question..."): answer = query_engine.answer_question(question) st.markdown("### ✅ Answer") st.success(answer) def show_data_preview(): """Show data preview and info with better formatting""" st.markdown("### 📋 Data Preview") st.markdown("---") col1, col2, col3 = st.columns(3) with col1: st.metric("📊 Total Rows", f"{len(st.session_state.df):,}") with col2: st.metric("📋 Total Columns", len(st.session_state.df.columns)) with col3: memory = st.session_state.df.memory_usage(deep=True).sum() / 1024**2 st.metric("💾 Memory Usage", f"{memory:.2f} MB") st.markdown("---") st.markdown("### 📄 Data Sample (First 100 rows)") # Create a copy for display display_df = st.session_state.df.head(100).copy() # Clean datetime columns for better display for col in display_df.columns: if 'datetime' in col.lower() or 'date' in col.lower() or 'time' in col.lower(): try: display_df[col] = pd.to_datetime(display_df[col]).dt.strftime('%Y-%m-%d %H:%M:%S') except: pass st.dataframe(display_df, use_container_width=True) st.markdown("---") st.markdown("### 📊 Column Information") col_info = pd.DataFrame({ 'Column': st.session_state.df.columns, 'Type': st.session_state.df.dtypes.astype(str), 'Non-Null': st.session_state.df.count().values, 'Nulls': st.session_state.df.isnull().sum().values, 'Unique': st.session_state.df.nunique().values }) st.dataframe(col_info, use_container_width=True) def show_welcome(): """Welcome screen""" st.markdown("""

🚀 Welcome to Smart Analytics Copilot

Upload any CSV or JSON file and let AI analyze it instantly


👈 Get Started: Upload a file or load a saved session from the sidebar

""", unsafe_allow_html=True) col1, col2, col3 = st.columns(3) with col1: st.markdown("""

📊 Auto Dashboard

Smart charts based on your data

""", unsafe_allow_html=True) with col2: st.markdown("""

💡 AI Insights

Natural language explanations

""", unsafe_allow_html=True) with col3: st.markdown("""

🎨 Custom Charts

Build your own visualizations

""", unsafe_allow_html=True) if __name__ == "__main__": main()