File size: 4,598 Bytes
ae15120
05e78d7
 
 
6e2134f
dfbae8c
1f78d55
05e78d7
 
 
 
 
 
 
 
6e2134f
05e78d7
 
dfbae8c
05e78d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dfbae8c
 
05e78d7
dfbae8c
05e78d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dfbae8c
6e2134f
05e78d7
 
1f78d55
05e78d7
 
 
 
 
 
 
 
 
 
 
 
 
dfbae8c
05e78d7
 
 
 
 
 
 
 
 
 
dfbae8c
05e78d7
 
 
 
 
dfbae8c
6e2134f
05e78d7
 
 
 
 
 
dfbae8c
05e78d7
1f78d55
05e78d7
 
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
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}")