import streamlit as st import pandas as pd import requests import json # Define your API key and endpoint api_key = 'AIzaSyAQ4dXlOkF8rPC21f6omTS4p6v-uJ2vVIg' url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent" headers = {'Content-Type': 'application/json'} # Cache the sentiment analysis function to improve performance @st.cache_data def analyze_sentiment(text): """ Analyze the sentiment of the given text using the Gemini API. """ system_prompt = """ You are a Sentiment Analysis Tool (SEA). Analyze the following comments and classify the sentiment of each as positive, neutral, or negative. Return the results in the following format: Comment: Sentiment: --- Additionally, provide actionable insights into customer satisfaction trends in the following format: ### Suggestions for Improvement: - - """ data = { "contents": [{ "parts": [{"text": f"{system_prompt}\n\n{text}"}] }] } response = requests.post(url, headers=headers, json=data, params={'key': api_key}) if response.status_code == 200: return response.json() else: st.error(f"Request failed with status code {response.status_code}: {response.text}") return None def read_file_content(file, file_type): """ Read the entire content of the file based on its type. """ if file_type == 'csv': df = pd.read_csv(file) text = ' '.join(df.apply(lambda x: ' '.join(x.dropna().astype(str)), axis=1)) elif file_type == 'xlsx': df = pd.read_excel(file) text = ' '.join(df.apply(lambda x: ' '.join(x.dropna().astype(str)), axis=1)) elif file_type == 'json': df = pd.read_json(file) text = ' '.join(df.apply(lambda x: ' '.join(x.dropna().astype(str)), axis=1)) elif file_type == 'txt' or file_type == 'md': text = file.read().decode('utf-8') else: st.error("Unsupported file type.") return None return text def process_large_text(text, chunk_size=5000): """ Split large text into smaller chunks for processing. """ chunks = [text[i:i + chunk_size] for i in range(0, len(text), chunk_size)] return chunks def display_sentiment_results(response_text, file_name): """ Display sentiment analysis results for a single file. """ # Parse comments and sentiments results = [] lines = response_text.split('\n') comment = None sentiment = None for line in lines: if line.startswith("Comment:"): comment = line.replace("Comment:", "").strip() elif line.startswith("Sentiment:"): sentiment = line.replace("Sentiment:", "").strip() if comment and sentiment: results.append((comment, sentiment)) comment = None sentiment = None # Display results st.write(f"### Sentiment Analysis Results for **{file_name}**") df_results = pd.DataFrame(results, columns=['Comment/Prompt', 'Sentiment']) st.dataframe(df_results) # Sentiment distribution sentiment_counts = df_results['Sentiment'].value_counts().reset_index() sentiment_counts.columns = ['Sentiment', 'Count'] with st.expander(f"View Sentiment Distribution for {file_name}"): st.bar_chart(sentiment_counts.set_index('Sentiment')) # Suggestions suggestions = [] current_section = None for line in lines: if line.startswith("### Suggestions for Improvement:"): current_section = "Suggestions for Improvement" elif current_section and line.startswith("- "): suggestions.append(line.replace("- ", "").strip()) if suggestions: st.write("### Suggestions for Improvement") for suggestion in suggestions: st.write(f"- {suggestion}") else: st.warning("No suggestions available.") # CSV download output_file = f"sentiment_analysis_results_{file_name}.csv" df_results.to_csv(output_file, index=False) st.download_button( label=f"Download Results for {file_name} as CSV", data=open(output_file, 'rb').read(), file_name=output_file, mime='text/csv', ) # Streamlit layout st.set_page_config(page_title="Sentiment Analysis Tool", layout="wide") st.title("Sentiment Analysis Tool (SEA) 💬") st.write("Analyze customer feedback with sentiment classification and actionable insights.") # Sidebar for instructions with st.sidebar: st.header("Instructions 📄") st.write(""" 1. Upload one or more files containing customer feedback in the main area. 2. Analyze real-time feedback using the text input box. 3. Download sentiment analysis results as CSV files. """) st.write("---") st.header("About") st.write("This app uses the Gemini API for sentiment analysis and provides actionable insights.") # Main layout with tabs tab1, tab2 = st.tabs(["📁 File Analysis", "✍️ Real-Time Feedback"]) with tab1: st.write("### Upload one or more files for batch sentiment analysis:") uploaded_files = st.file_uploader("Choose files", type=["csv", "xlsx", "json", "txt", "md"], accept_multiple_files=True) if uploaded_files: for uploaded_file in uploaded_files: file_type = uploaded_file.name.split('.')[-1] with st.spinner(f"Processing {uploaded_file.name}..."): # Read the entire file content text = read_file_content(uploaded_file, file_type) if text: # Process large text in chunks if necessary chunks = process_large_text(text) combined_results = "" for chunk in chunks: sentiment_result = analyze_sentiment(chunk) if sentiment_result: response_text = sentiment_result.get('candidates', [{}])[0].get('content', {}).get('parts', [{}])[0].get('text', '').strip() combined_results += response_text + "\n" if combined_results: display_sentiment_results(combined_results, uploaded_file.name) else: st.error(f"Sentiment analysis failed for {uploaded_file.name}.") with tab2: st.write("### Enter your feedback for real-time analysis:") feedback_input = st.text_area("Enter your feedback:", placeholder="Type your feedback here...") if st.button("Analyze Sentiment"): if feedback_input.strip() == "": st.warning("Please enter some feedback to analyze.") else: with st.spinner("Analyzing sentiment..."): sentiment_result = analyze_sentiment(feedback_input) if sentiment_result: sentiment = sentiment_result.get('candidates', [{}])[0].get('content', {}).get('parts', [{}])[0].get('text', '').strip().lower() if "positive" in sentiment: st.success(f"Sentiment: **Positive** 😊") elif "neutral" in sentiment: st.info(f"Sentiment: **Neutral** 😐") elif "negative" in sentiment: st.error(f"Sentiment: **Negative** 😠") else: st.warning(f"Sentiment: **Unknown** 🤔") else: st.error("Sentiment analysis failed.")