Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import anthropic | |
| import base64 | |
| import plotly.express as px | |
| from datetime import datetime | |
| import json | |
| from pathlib import Path | |
| from utils import EmbeddingManager | |
| def send_to_llm(user_query, data, df): | |
| """Send data chunks to the LLM and get a response.""" | |
| columns = df.columns.tolist() | |
| dtypes = df.dtypes.to_dict() | |
| summary_stats = df.describe().to_json() | |
| client = anthropic.AnthropicBedrock() | |
| prompt = """You are a data analysis expert. Your task is to generate a complete, standalone HTML report. | |
| You MUST return ONLY valid HTML code that starts with <!DOCTYPE html> and includes all necessary elements. | |
| Data Details: | |
| - Columns: {columns} | |
| - Data Types: {dtypes} | |
| - Summary Stats: {summary_stats} | |
| Required HTML Structure: | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <!-- Include Plotly CDN --> | |
| <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> | |
| <style> | |
| /* Add your CSS styling here */ | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Report content goes here --> | |
| </body> | |
| </html> | |
| Requirements: | |
| 1. Create visualizations using Plotly.js | |
| 2. Include executive summary, insights, and analysis | |
| 3. Add proper styling and make it visually appealing | |
| 4. Ensure all Plotly charts have proper div containers | |
| 5. Include the current date | |
| DO NOT include any explanatory text outside the HTML code. Return ONLY the complete HTML document.""" | |
| message = client.messages.create( | |
| model="anthropic.claude-3-5-sonnet-20240620-v1:0", | |
| max_tokens=4096, # Increased token limit for full HTML response | |
| system=prompt, | |
| messages=[{ | |
| "role": "user", | |
| "content": f"Generate a complete HTML report analyzing this data: {str(data)} \nUser query: {user_query}" | |
| }] | |
| ) | |
| # Extract only the HTML content | |
| response_text = message.content[0].text | |
| if "<!DOCTYPE html>" not in response_text: | |
| # Fallback if response isn't proper HTML | |
| return f""" | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> | |
| </head> | |
| <body> | |
| <h1>Analysis Report</h1> | |
| {response_text} | |
| </body> | |
| </html> | |
| """ | |
| return response_text | |
| def create_chunks_and_send(data_dict: dict, filename): | |
| """Process each sheet separately and combine their chunks""" | |
| all_chunks = [] | |
| for sheet_name, df in data_dict.items(): | |
| # Reset index for each DataFrame | |
| df = df.reset_index(drop=True) | |
| output_dir = Path('./output') | |
| embeddings_dir = output_dir / 'embeddings' / filename / sheet_name | |
| if embeddings_dir.exists(): | |
| chunks_file = embeddings_dir / "chunks.json" | |
| if chunks_file.is_file(): | |
| with open(chunks_file, "r", encoding="utf-8") as f: | |
| sheet_chunks = json.load(f) | |
| all_chunks.extend(sheet_chunks) | |
| else: | |
| embeddings_dir.mkdir(parents=True, exist_ok=True) | |
| embedding_manager = EmbeddingManager(output_dir=Path('./output')) | |
| # Convert DataFrame to JSON with orient='records' | |
| text = df.to_json(orient='records') | |
| sheet_chunks, _ = embedding_manager.process_script(data=str(text), filename=f"{filename}_{sheet_name}") | |
| all_chunks.extend(sheet_chunks) | |
| return all_chunks | |
| def main(): | |
| st.title("Excel Chatbot") | |
| query = st.text_input("Enter the query") | |
| # File upload | |
| uploaded_file = st.file_uploader("Upload Excel File", type=['xlsx', 'xls']) | |
| if uploaded_file and query: | |
| try: | |
| # Read Excel without concatenating sheets | |
| df_dict = pd.read_excel(uploaded_file, sheet_name=None) | |
| st.success("File uploaded successfully!") | |
| # Show preview of each sheet | |
| for sheet_name, df in df_dict.items(): | |
| st.subheader(f"Data Preview - {sheet_name}") | |
| st.dataframe(df) | |
| with st.spinner("Generating response with Claude..."): | |
| # Process all sheets and get combined chunks | |
| data = create_chunks_and_send(df_dict, uploaded_file.name) | |
| # Get complete HTML report from Claude | |
| response = send_to_llm(user_query=query, data=data, df=pd.concat(df_dict.values())) | |
| # Get the HTML content (ensure it's a string) | |
| html_report = ''.join(str(message.text) for message in response.content) | |
| st.components.v1.html(html_report, height=800, scrolling=True) | |
| st.success("Report generated successfully! Click the link above to download.") | |
| except Exception as e: | |
| st.error(f"An error occurred: {str(e)}") | |
| #st.error("Please check your API key and file format, then try again.") | |
| if __name__ == "__main__": | |
| main() | |