# frontend/app.py import streamlit as st import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import sys import os # Add the parent directory of 'backend' to the Python path # This allows importing 'backend' as a package # os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) points to 'sentilyze/' sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) # Import functions directly from the 'backend' package # The __init__.py in backend handles the individual imports from backend import analyze_sentiment, process_csv_for_dashboard, detect_sarcasm_and_highlight # --- Streamlit App Configuration --- st.set_page_config( page_title="Sentilyze - Sentiment & Sarcasm Analyzer", page_icon="✨", layout="wide", initial_sidebar_state="expanded" ) # --- Custom CSS for better aesthetics --- st.markdown(""" """, unsafe_allow_html=True) # --- Header --- st.markdown("

Sentilyze ✨

", unsafe_allow_html=True) st.write("Analyze sentiment, detect sarcasm, and visualize insights from your text data.") # --- Navigation (using Streamlit's sidebar for sections) --- st.sidebar.title("Navigation") page = st.sidebar.radio("Go to", ["Single Text Analysis", "CSV File Analysis", "About"]) # --- Single Text Analysis Section --- if page == "Single Text Analysis": st.header("Analyze Single Text") user_input = st.text_area("Enter text here:", "This product is absolutely fantastic!", height=150) col1, col2 = st.columns(2) with col1: if st.button("Analyze Sentiment"): if user_input: sentiment_result = analyze_sentiment(user_input) st.success(f"**Sentiment:** {sentiment_result['class'].capitalize()}") st.info(f"**Polarity Score:** {sentiment_result['polarity']:.2f} (closer to 1 is positive, -1 is negative)") else: st.warning("Please enter some text to analyze sentiment.") with col2: if st.button("Detect Sarcasm"): if user_input: sarcasm_result = detect_sarcasm_and_highlight(user_input) st.success(f"**Sarcasm Probability:** {sarcasm_result['sarcasm_percent']:.2f}%") # FIX: Changed 'predicted_sentiment_label' to 'predicted_sarcasm_label' st.info(f"**Predicted Sarcasm (Model's view):** {sarcasm_result['predicted_sarcasm_label'].capitalize()}") st.markdown(f"**Highlighted Text:** {sarcasm_result['highlighted_sentence']}", unsafe_allow_html=True) if "note" in sarcasm_result: st.caption(f"Note: {sarcasm_result['note']}") else: st.warning("Please enter some text to detect sarcasm.") # --- CSV File Analysis Section --- elif page == "CSV File Analysis": st.header("Analyze CSV File") st.write("Upload a CSV file containing text data for sentiment analysis and dashboard visualization.") uploaded_file = st.file_uploader("Choose a CSV file", type="csv") if uploaded_file is not None: # Save the uploaded file temporarily to process it with pandas # In a real app, consider more robust temporary file handling or direct BytesIO temp_filepath = os.path.join("data", uploaded_file.name) with open(temp_filepath, "wb") as f: f.write(uploaded_file.getbuffer()) df = process_csv_for_dashboard(temp_filepath) if not df.empty: st.success("CSV file uploaded and processed successfully!") st.subheader("Raw Data Preview:") st.dataframe(df.head()) # Allow user to select the text column text_columns = [col for col in df.columns if df[col].dtype == 'object'] # Assuming text is object/string type if not text_columns: st.error("No text columns found in the CSV. Please ensure your CSV has columns with review text.") else: selected_text_column = st.selectbox( "Select the column containing text/reviews for analysis:", text_columns ) if st.button(f"Perform Sentiment Analysis on '{selected_text_column}'"): with st.spinner("Analyzing sentiment... This might take a while for large files."): # Apply sentiment analysis to the selected column df['Sentiment'] = df[selected_text_column].astype(str).apply(lambda x: analyze_sentiment(x)['class']) df['Polarity'] = df[selected_text_column].astype(str).apply(lambda x: analyze_sentiment(x)['polarity']) st.subheader("Sentiment Analysis Results:") st.dataframe(df[[selected_text_column, 'Sentiment', 'Polarity']].head()) st.subheader("Sentiment Distribution:") sentiment_counts = df['Sentiment'].value_counts() st.bar_chart(sentiment_counts) # Interactive Dashboard Elements st.subheader("Interactive Dashboard") # Pie chart for sentiment distribution fig1, ax1 = plt.subplots() sentiment_counts.plot.pie(autopct='%1.1f%%', startangle=90, ax=ax1, colors=['#4CAF50', '#FFC107', '#F44336']) # Positive, Neutral, Negative ax1.set_ylabel('') # Hide the default 'Sentiment' label ax1.set_title('Overall Sentiment Distribution') st.pyplot(fig1) # Histogram of Polarity Scores fig2, ax2 = plt.subplots() sns.histplot(df['Polarity'], bins=20, kde=True, ax=ax2, color='#2196F3') ax2.set_title('Distribution of Polarity Scores') ax2.set_xlabel('Polarity Score') ax2.set_ylabel('Frequency') st.pyplot(fig2) # Display data by sentiment type st.subheader("View Data by Sentiment Type") sentiment_filter = st.selectbox( "Filter by Sentiment:", ["All", "positive", "neutral", "negative"] ) if sentiment_filter == "All": st.dataframe(df[[selected_text_column, 'Sentiment', 'Polarity']]) else: filtered_df = df[df['Sentiment'] == sentiment_filter] st.dataframe(filtered_df[[selected_text_column, 'Sentiment', 'Polarity']]) else: st.error("Could not process the CSV file. Please check its format.") # Clean up the temporary file if os.path.exists(temp_filepath): os.remove(temp_filepath) # --- About Section --- elif page == "About": st.header("About Sentilyze") st.write(""" Sentilyze is a web application designed to help you understand the sentiment and nuances of text data. It offers: - **Single Text Analysis:** Quickly determine the sentiment (positive, neutral, negative) and potential sarcasm of individual pieces of text. - **CSV File Analysis:** Upload your own datasets (e.g., customer reviews, social media comments) and get an interactive dashboard showing sentiment distribution and polarity. - **Sarcasm Detection:** A feature to estimate the sarcasm percentage in a sentence, with basic highlighting (note: advanced sarcasm highlighting is a complex NLP task). **Technologies Used:** - **Backend:** Python, `pandas`, `TextBlob`, `transformers` (Hugging Face) - **Frontend:** Streamlit - **Deployment:** Docker, GitHub, (potential platforms like Streamlit Community Cloud, Heroku, Render) **Developed by:** [Your Name/Team Name Here] """) st.markdown("[GitHub Repository (Coming Soon!)](#)", unsafe_allow_html=True) # --- Footer --- st.markdown("""

Sentilyze © 2023

""", unsafe_allow_html=True)