Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import io | |
| from utils import query_agent, detect_delimiter | |
| from dotenv import load_dotenv | |
| import os | |
| # Set Streamlit page configuration | |
| st.set_page_config( | |
| page_title="HF Data Analyst Agent", | |
| page_icon="π", | |
| layout="centered" | |
| ) | |
| # Load environment variables | |
| load_dotenv() | |
| # Retrieve API Token from .env or environment variables | |
| HUGGINGFACEHUB_API_TOKEN = os.getenv("HUGGINGFACEHUB_API_TOKEN") | |
| # --- Custom Styling (Tailwind-like aesthetic using Streamlit's style) --- | |
| st.markdown(""" | |
| <style> | |
| .main-header { | |
| font-size: 2.5em; | |
| font-weight: 700; | |
| color: #4B0082; /* Deep Purple */ | |
| text-align: center; | |
| margin-bottom: 0.5em; | |
| } | |
| .stButton>button { | |
| background-color: #6A5ACD; /* Slate Blue */ | |
| color: white; | |
| border-radius: 12px; | |
| border: 2px solid #483D8B; | |
| padding: 10px 20px; | |
| font-size: 16px; | |
| transition: all 0.3s ease; | |
| } | |
| .stButton>button:hover { | |
| background-color: #483D8B; /* Darker Blue */ | |
| color: #E0FFFF; | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); | |
| } | |
| .uploaded-file-details { | |
| margin-top: 15px; | |
| padding: 15px; | |
| border: 1px solid #DDA0DD; /* Plum */ | |
| border-radius: 10px; | |
| background-color: #F8F8FF; /* Ghost White */ | |
| } | |
| .analysis-input-box { | |
| margin-top: 20px; | |
| padding: 20px; | |
| border: 2px solid #7B68EE; /* Medium Slate Blue */ | |
| border-radius: 15px; | |
| background-color: #E6E6FA; /* Lavender */ | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # --- Application Title and Setup --- | |
| st.markdown('<div class="main-header">π AI Data Analyst powered by Mistral (HF)</div>', unsafe_allow_html=True) | |
| st.markdown( | |
| """ | |
| Upload a CSV file and ask natural language questions about your data. | |
| This application uses the **Mistral-7B-Instruct-v0.2** model via the Hugging Face Inference Endpoint for fast, accurate analysis. | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| if not HUGGINGFACEHUB_API_TOKEN or HUGGINGFACEHUB_API_TOKEN == "YOUR_HUGGINGFACE_TOKEN_HERE": | |
| st.error("β οΈ **API Token Missing!** Please set your `HUGGINGFACEHUB_API_TOKEN` in the `.env` file or as a secret in your Hugging Face Space.") | |
| else: | |
| # --- File Uploader --- | |
| uploaded_file = st.file_uploader( | |
| "Upload your CSV file", | |
| type=["csv"], | |
| accept_multiple_files=False, | |
| help="Upload a CSV file. The app automatically detects delimiters (like comma, semicolon, etc.)." | |
| ) | |
| if uploaded_file is not None: | |
| # Read the file content into bytes | |
| file_content_bytes = uploaded_file.getvalue() | |
| st.markdown('<div class="uploaded-file-details">', unsafe_allow_html=True) | |
| st.subheader("Data Preview (First 5 Rows)") | |
| try: | |
| delimiter = detect_delimiter(file_content_bytes) | |
| # Read the DataFrame just for display | |
| data_io = io.StringIO(file_content_bytes.decode('utf-8')) | |
| df_preview = pd.read_csv(data_io, sep=delimiter) | |
| st.dataframe(df_preview.head()) | |
| st.write(f"Detected Delimiter: `{delimiter}`") | |
| st.write(f"Shape: {df_preview.shape[0]} rows, {df_preview.shape[1]} columns") | |
| # --- Analysis Input Box --- | |
| st.markdown('</div>', unsafe_allow_html=True) | |
| st.markdown('<div class="analysis-input-box">', unsafe_allow_html=True) | |
| st.subheader("Ask a question about the data") | |
| query = st.text_input( | |
| "Enter your question here:", | |
| placeholder="e.g., What is the average value of the 'Age' column?", | |
| key="user_query" | |
| ) | |
| # --- Analysis Execution --- | |
| if st.button("Run Analysis", key="run_analysis_button") and query: | |
| with st.spinner("Analyzing data... The Mistral Agent is working hard!"): | |
| # Pass the Hugging Face API token to the agent function | |
| response = query_agent(file_content_bytes, query, HUGGINGFACEHUB_API_TOKEN) | |
| st.success("Analysis Complete!") | |
| st.markdown("---") | |
| st.subheader("Agent Response") | |
| st.markdown(f"**{response}**") | |
| elif st.button("Run Analysis", key="run_analysis_button_disabled") and not query: | |
| st.warning("Please enter a question to analyze the data.") | |
| st.markdown('</div>', unsafe_allow_html=True) | |
| except Exception as e: | |
| st.error(f"Could not process the uploaded file or generate preview. Error: {e}") |