CCockrum commited on
Commit
f3e978b
Β·
verified Β·
1 Parent(s): df2c577

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +297 -0
app.py CHANGED
@@ -11,6 +11,18 @@ import json
11
  import os
12
  import sqlite3
13
  from datetime import datetime
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  class DataAnalysisChatbot:
16
  def __init__(self):
@@ -1275,6 +1287,291 @@ class DataAnalysisChatbot:
1275
  help_text += " correlate temperature humidity pressure\n"
1276
  help_text += " visualize scatter temperature humidity\n"
1277
  help_text += " trend sales date\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1278
 
1279
  return help_text
1280
 
 
11
  import os
12
  import sqlite3
13
  from datetime import datetime
14
+ import streamlit as st
15
+ import pandas as pd
16
+ import matplotlib.pyplot as plt
17
+ import seaborn as sns
18
+ import os
19
+ import io
20
+ from datetime import datetime
21
+ import base64
22
+ from PIL import Image
23
+
24
+ # Import the DataAnalysisChatbot class
25
+ from paste import DataAnalysisChatbot
26
 
27
  class DataAnalysisChatbot:
28
  def __init__(self):
 
1287
  help_text += " correlate temperature humidity pressure\n"
1288
  help_text += " visualize scatter temperature humidity\n"
1289
  help_text += " trend sales date\n"
1290
+
1291
+
1292
+ # Page configuration
1293
+ st.set_page_config(
1294
+ page_title="Data Analysis Assistant",
1295
+ page_icon="πŸ“Š",
1296
+ layout="wide",
1297
+ initial_sidebar_state="expanded"
1298
+ )
1299
+
1300
+ # Initialize session state variables if they don't exist
1301
+ if 'chatbot' not in st.session_state:
1302
+ st.session_state.chatbot = DataAnalysisChatbot()
1303
+ if 'conversation' not in st.session_state:
1304
+ st.session_state.conversation = []
1305
+ if 'data_loaded' not in st.session_state:
1306
+ st.session_state.data_loaded = False
1307
+ if 'current_file' not in st.session_state:
1308
+ st.session_state.current_file = None
1309
+ if 'data_preview' not in st.session_state:
1310
+ st.session_state.data_preview = None
1311
+
1312
+ # Function to get a download link for a file
1313
+ def get_download_link(file_path, link_text):
1314
+ with open(file_path, 'rb') as f:
1315
+ data = f.read()
1316
+ b64 = base64.b64encode(data).decode()
1317
+ href = f'<a href="data:file/txt;base64,{b64}" download="{os.path.basename(file_path)}">{link_text}</a>'
1318
+ return href
1319
+
1320
+ # Function to convert matplotlib figure to Streamlit-compatible format
1321
+ def plt_to_streamlit():
1322
+ buf = io.BytesIO()
1323
+ plt.savefig(buf, format='png')
1324
+ buf.seek(0)
1325
+ return buf
1326
+
1327
+ # Custom CSS
1328
+ st.markdown("""
1329
+ <style>
1330
+ .main-header {
1331
+ font-size: 2.5rem;
1332
+ font-weight: 700;
1333
+ color: #1E88E5;
1334
+ margin-bottom: 1rem;
1335
+ }
1336
+ .sub-header {
1337
+ font-size: 1.5rem;
1338
+ font-weight: 600;
1339
+ color: #333;
1340
+ margin-bottom: 1rem;
1341
+ }
1342
+ .chat-user {
1343
+ background-color: #E3F2FD;
1344
+ padding: 10px 15px;
1345
+ border-radius: 15px;
1346
+ margin-bottom: 10px;
1347
+ font-size: 1rem;
1348
+ }
1349
+ .chat-bot {
1350
+ background-color: #F5F5F5;
1351
+ padding: 10px 15px;
1352
+ border-radius: 15px;
1353
+ margin-bottom: 10px;
1354
+ font-size: 1rem;
1355
+ }
1356
+ .file-info {
1357
+ padding: 10px;
1358
+ background-color: #E8F5E9;
1359
+ border-radius: 5px;
1360
+ margin-bottom: 10px;
1361
+ }
1362
+ .sidebar-content {
1363
+ padding: 10px;
1364
+ }
1365
+ .highlight-text {
1366
+ color: #1E88E5;
1367
+ font-weight: bold;
1368
+ }
1369
+ .stButton>button {
1370
+ width: 100%;
1371
+ }
1372
+ </style>
1373
+ """, unsafe_allow_html=True)
1374
+
1375
+ # Sidebar for data loading and information
1376
+ with st.sidebar:
1377
+ st.markdown('<div class="sidebar-content">', unsafe_allow_html=True)
1378
+ st.markdown('<p class="sub-header">πŸ“ Data Loading</p>', unsafe_allow_html=True)
1379
+
1380
+ # File uploader
1381
+ uploaded_file = st.file_uploader("Upload your data file", type=['csv', 'xlsx', 'json', 'db', 'sqlite'])
1382
+
1383
+ # Load data button (only show if file is uploaded)
1384
+ if uploaded_file is not None:
1385
+ file_type = uploaded_file.name.split('.')[-1].lower()
1386
+
1387
+ # Save the uploaded file to a temporary location
1388
+ temp_file_path = f"temp_upload_{datetime.now().strftime('%Y%m%d%H%M%S')}.{file_type}"
1389
+ with open(temp_file_path, "wb") as f:
1390
+ f.write(uploaded_file.getbuffer())
1391
+
1392
+ # Load data based on file type
1393
+ if st.button("Load Data"):
1394
+ try:
1395
+ if file_type == 'csv':
1396
+ response = st.session_state.chatbot.process_query(f"load csv {temp_file_path}")
1397
+ elif file_type in ['xlsx', 'xls']:
1398
+ response = st.session_state.chatbot.process_query(f"load excel {temp_file_path}")
1399
+ elif file_type == 'json':
1400
+ response = st.session_state.chatbot.process_query(f"load json {temp_file_path}")
1401
+ elif file_type in ['db', 'sqlite']:
1402
+ # For SQL databases, we need to prompt for a query
1403
+ st.session_state.current_file = temp_file_path
1404
+ st.session_state.data_loaded = False
1405
+ response = "SQL database loaded. Please enter a query in the main chat."
1406
+ else:
1407
+ response = "Unsupported file format. Please upload CSV, Excel, JSON, or SQLite files."
1408
+
1409
+ st.session_state.conversation.append({"role": "user", "message": f"Loading {uploaded_file.name}"})
1410
+ st.session_state.conversation.append({"role": "bot", "message": response})
1411
+
1412
+ if "Successfully loaded data" in response:
1413
+ st.session_state.data_loaded = True
1414
+ st.session_state.current_file = temp_file_path
1415
+
1416
+ # Get data preview
1417
+ if st.session_state.chatbot.data is not None:
1418
+ st.session_state.data_preview = st.session_state.chatbot.data.head()
1419
+ except Exception as e:
1420
+ st.error(f"Error loading data: {str(e)}")
1421
+
1422
+ # Display data information if data is loaded
1423
+ if st.session_state.data_loaded and st.session_state.chatbot.data is not None:
1424
+ st.markdown('<p class="sub-header">πŸ“Š Data Information</p>', unsafe_allow_html=True)
1425
+
1426
+ # Display basic info
1427
+ st.markdown('<div class="file-info">', unsafe_allow_html=True)
1428
+ st.write(f"**Rows:** {len(st.session_state.chatbot.data)}")
1429
+ st.write(f"**Columns:** {len(st.session_state.chatbot.data.columns)}")
1430
+ st.write(f"**Data Source:** {st.session_state.chatbot.data_source}")
1431
+ st.markdown('</div>', unsafe_allow_html=True)
1432
+
1433
+ # Quick actions
1434
+ st.markdown('<p class="sub-header">⚑ Quick Actions</p>', unsafe_allow_html=True)
1435
+
1436
+ col1, col2 = st.columns(2)
1437
+ with col1:
1438
+ if st.button("Describe Data"):
1439
+ response = st.session_state.chatbot.process_query("describe")
1440
+ st.session_state.conversation.append({"role": "user", "message": "Describe data"})
1441
+ st.session_state.conversation.append({"role": "bot", "message": response})
1442
+
1443
+ with col2:
1444
+ if st.button("Check Missing"):
1445
+ response = st.session_state.chatbot.process_query("missing")
1446
+ st.session_state.conversation.append({"role": "user", "message": "Check missing values"})
1447
+ st.session_state.conversation.append({"role": "bot", "message": response})
1448
+
1449
+ col1, col2 = st.columns(2)
1450
+ with col1:
1451
+ if st.button("Correlations"):
1452
+ response = st.session_state.chatbot.process_query("correlate")
1453
+ st.session_state.conversation.append({"role": "user", "message": "Show correlations"})
1454
+ st.session_state.conversation.append({"role": "bot", "message": response})
1455
+
1456
+ with col2:
1457
+ if st.button("Generate Report"):
1458
+ response = st.session_state.chatbot.process_query("report")
1459
+ st.session_state.conversation.append({"role": "user", "message": "Generate report"})
1460
+ st.session_state.conversation.append({"role": "bot", "message": response})
1461
+
1462
+ # If report was generated, provide download link
1463
+ if "Report generated and saved as" in response:
1464
+ report_filename = response.split("Report generated and saved as ")[-1].strip()
1465
+ st.markdown(
1466
+ get_download_link(report_filename, "πŸ“₯ Download Report"),
1467
+ unsafe_allow_html=True
1468
+ )
1469
+
1470
+ # Help section
1471
+ st.markdown('<p class="sub-header">❓ Help</p>', unsafe_allow_html=True)
1472
+ if st.button("Show Commands"):
1473
+ response = st.session_state.chatbot.process_query("help")
1474
+ st.session_state.conversation.append({"role": "user", "message": "Show available commands"})
1475
+ st.session_state.conversation.append({"role": "bot", "message": response})
1476
+
1477
+ st.markdown('</div>', unsafe_allow_html=True)
1478
+
1479
+ # Main area
1480
+ st.markdown('<h1 class="main-header">πŸ“Š Data Analysis Assistant</h1>', unsafe_allow_html=True)
1481
+
1482
+ # Show data preview if data is loaded
1483
+ if st.session_state.data_loaded and st.session_state.data_preview is not None:
1484
+ st.markdown('<p class="sub-header">Data Preview</p>', unsafe_allow_html=True)
1485
+ st.dataframe(st.session_state.data_preview, use_container_width=True)
1486
+
1487
+ # Display conversation history
1488
+ st.markdown('<p class="sub-header">Chat History</p>', unsafe_allow_html=True)
1489
+ chat_container = st.container()
1490
+
1491
+ with chat_container:
1492
+ for message in st.session_state.conversation:
1493
+ if message["role"] == "user":
1494
+ st.markdown(f'<div class="chat-user">πŸ‘€ <b>You:</b> {message["message"]}</div>', unsafe_allow_html=True)
1495
+ else:
1496
+ # Process bot messages for special content
1497
+ bot_message = message["message"]
1498
+
1499
+ # Check if it's a visualization result
1500
+ if "Visualization created and saved as" in bot_message:
1501
+ # Extract the filename and load the image
1502
+ img_file = bot_message.split("Visualization created and saved as ")[-1].strip()
1503
+ if os.path.exists(img_file):
1504
+ st.markdown(f'<div class="chat-bot">πŸ€– <b>Assistant:</b></div>', unsafe_allow_html=True)
1505
+ try:
1506
+ img = Image.open(img_file)
1507
+ st.image(img, caption="Generated Visualization", use_column_width=True)
1508
+ except Exception as e:
1509
+ st.error(f"Error displaying visualization: {str(e)}")
1510
+ st.markdown(f'<div class="chat-bot">πŸ€– <b>Assistant:</b> {bot_message}</div>', unsafe_allow_html=True)
1511
+ else:
1512
+ st.markdown(f'<div class="chat-bot">πŸ€– <b>Assistant:</b> {bot_message}</div>', unsafe_allow_html=True)
1513
+
1514
+ # Check if it's a report result
1515
+ elif "Report generated and saved as" in bot_message:
1516
+ report_filename = bot_message.split("Report generated and saved as ")[-1].strip()
1517
+ st.markdown(
1518
+ f'<div class="chat-bot">πŸ€– <b>Assistant:</b> {bot_message}<br/>{get_download_link(report_filename, "πŸ“₯ Download Report")}</div>',
1519
+ unsafe_allow_html=True
1520
+ )
1521
+
1522
+ # Regular message
1523
+ else:
1524
+ # Format code blocks
1525
+ if "```" in bot_message:
1526
+ parts = bot_message.split("```")
1527
+ formatted_message = ""
1528
+ for i, part in enumerate(parts):
1529
+ if i % 2 == 0: # Outside code block
1530
+ formatted_message += part
1531
+ else: # Inside code block
1532
+ formatted_message += f"<pre style='background-color: #f0f0f0; padding: 10px; border-radius: 5px; overflow-x: auto;'>{part}</pre>"
1533
+ st.markdown(f'<div class="chat-bot">πŸ€– <b>Assistant:</b> {formatted_message}</div>', unsafe_allow_html=True)
1534
+ else:
1535
+ st.markdown(f'<div class="chat-bot">πŸ€– <b>Assistant:</b> {bot_message}</div>', unsafe_allow_html=True)
1536
+
1537
+ # User input
1538
+ st.markdown('<p class="sub-header">Ask a Question</p>', unsafe_allow_html=True)
1539
+ user_input = st.text_area("Enter your query", height=100, key="user_query")
1540
+
1541
+ # Handle SQL query case
1542
+ if st.session_state.current_file is not None and not st.session_state.data_loaded and st.session_state.current_file.endswith(('db', 'sqlite')):
1543
+ sql_query = st.text_area("Enter SQL query", height=100, key="sql_query")
1544
+ if st.button("Run SQL Query") and sql_query:
1545
+ response = st.session_state.chatbot.process_query(f"load sql {st.session_state.current_file} query {sql_query}")
1546
+ st.session_state.conversation.append({"role": "user", "message": f"SQL query: {sql_query}"})
1547
+ st.session_state.conversation.append({"role": "bot", "message": response})
1548
+
1549
+ if "Successfully loaded data" in response:
1550
+ st.session_state.data_loaded = True
1551
+ if st.session_state.chatbot.data is not None:
1552
+ st.session_state.data_preview = st.session_state.chatbot.data.head()
1553
+
1554
+ # Submit button for regular queries
1555
+ if st.button("Submit") and user_input:
1556
+ # Add user message to conversation
1557
+ st.session_state.conversation.append({"role": "user", "message": user_input})
1558
+
1559
+ # Process query
1560
+ response = st.session_state.chatbot.process_query(user_input)
1561
+
1562
+ # Add bot response to conversation
1563
+ st.session_state.conversation.append({"role": "bot", "message": response})
1564
+
1565
+ # Clear input
1566
+ st.session_state.user_query = ""
1567
+
1568
+ # Add warning for demo mode
1569
+ st.markdown("---")
1570
+ st.markdown("**Note:** File uploads and data processing are handled locally. Make sure you have the necessary dependencies installed.", unsafe_allow_html=True)
1571
+
1572
+ # Footer
1573
+ st.markdown("---")
1574
+ st.markdown("Β© 2025 Data Analysis Assistant | Built with Streamlit")
1575
 
1576
  return help_text
1577