Spaces:
Sleeping
Sleeping
File size: 5,174 Bytes
eb4b18c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | 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()
|