📊 Data Analyst Agent
Upload your data • Ask questions • Get insights, charts & reports
""" Data Analyst Agent - Streamlit Version Beautiful UI with Voice Input """ import streamlit as st import asyncio import os import base64 import tempfile from fastapi_poe.client import get_bot_response from fastapi_poe.types import ProtocolMessage, Attachment # Page config st.set_page_config( page_title="📊 Data Analyst Agent", page_icon="📊", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for beautiful UI st.markdown(""" """, unsafe_allow_html=True) # Get API key POE_API_KEY = os.environ.get("POE_API_KEY", "") SYSTEM_PROMPT = """You are a powerful data analysis agent. You can: 1. **Analyze Data**: Read CSV, Excel (.xlsx, .xls) files and perform comprehensive analysis 2. **Generate Visualizations**: Create charts using matplotlib, seaborn, plotly 3. **Execute Python Code**: Run any Python code for data manipulation and analysis 4. **Install Libraries**: Use `pip install` if a library is not available 5. **Create Reports**: Generate Word (.docx) or PowerPoint (.pptx) documents with charts and summaries ## Guidelines - When user uploads a file, first explore the data (shape, columns, dtypes, sample rows, missing values) - Create meaningful visualizations based on the data types and relationships - Always display charts inline so the user can see them - For reports, save charts as images first, then embed them in Word/PowerPoint - Be proactive: suggest insights and additional analyses the user might find valuable - When creating downloadable files, provide the download link""" async def transcribe_audio(audio_bytes: bytes) -> str: """Transcribe audio using Whisper via Poe API.""" if not audio_bytes: return "" try: b64_data = base64.b64encode(audio_bytes).decode("utf-8") data_url = f"data:audio/wav;base64,{b64_data}" attachment = Attachment(url=data_url, name="voice.wav", content_type="audio/wav") messages = [ProtocolMessage(role="user", content="Transcribe this audio accurately.", attachments=[attachment])] text = "" async for partial in get_bot_response(messages=messages, bot_name="Whisper-V3-Large-T", api_key=POE_API_KEY): text += partial.text return text.strip() except Exception as e: return f"Transcription error: {str(e)}" async def call_analyst(message: str, file_bytes: bytes = None, filename: str = None, history: list = None): """Call Claude-Code for analysis.""" if not POE_API_KEY: return "❌ **Error**: POE_API_KEY not set! Go to Settings → Secrets and add your Poe API key." messages = [ProtocolMessage(role="system", content=SYSTEM_PROMPT)] # Add history if history: for item in history: if item["role"] == "user": messages.append(ProtocolMessage(role="user", content=item["content"])) elif item["role"] == "assistant": messages.append(ProtocolMessage(role="assistant", content=item["content"])) # Handle file attachments = [] if file_bytes and filename: if filename.endswith(".csv"): ctype = "text/csv" elif filename.endswith(".xlsx"): ctype = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" else: ctype = "application/octet-stream" b64 = base64.b64encode(file_bytes).decode("utf-8") attachments.append(Attachment(url=f"data:{ctype};base64,{b64}", name=filename, content_type=ctype)) messages.append(ProtocolMessage(role="user", content=message, attachments=attachments)) response = "" try: async for partial in get_bot_response(messages=messages, bot_name="Claude-Code", api_key=POE_API_KEY): response += partial.text except Exception as e: response = f"❌ **API Error**: {str(e)}" return response def run_async(coro): """Run async function.""" loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: return loop.run_until_complete(coro) finally: loop.close() # Initialize session state if "messages" not in st.session_state: st.session_state.messages = [] if "file_bytes" not in st.session_state: st.session_state.file_bytes = None if "filename" not in st.session_state: st.session_state.filename = None # Header st.markdown("""
Upload your data • Ask questions • Get insights, charts & reports
Powered by Poe API • Claude-Code for intelligent analysis
", unsafe_allow_html=True )