"""Streamlit frontend for the News Summarization application.""" import streamlit as st import pandas as pd import json import os import plotly.express as px import altair as alt from utils import analyze_company_data # Import the analysis function directly # Set page config st.set_page_config( page_title="News Summarization App", page_icon="📰", layout="wide" ) # Show loading message with st.spinner("Initializing the application... Please wait while we load the models."): # Initialize components try: from utils import NewsExtractor, SentimentAnalyzer, TextSummarizer, TextToSpeechConverter st.success("Application initialized successfully!") except Exception as e: st.error(f"Error initializing application: {str(e)}") st.info("Please try refreshing the page.") def process_company(company_name): """Process company data directly.""" try: # Call the analysis function directly from utils data = analyze_company_data(company_name) # Generate audio if needed if 'summary' in data: from gtts import gTTS tts = gTTS(text=data['summary'], lang='en') audio_path = os.path.join('audio_output', f'{company_name}_summary.mp3') os.makedirs('audio_output', exist_ok=True) tts.save(audio_path) data['audio_path'] = audio_path return data except Exception as e: st.error(f"Error processing company: {str(e)}") return {"articles": [], "comparative_sentiment_score": {}, "final_sentiment_analysis": "", "audio_path": None} def main(): st.title("News Summarization App") st.write("Analyze news articles and get sentiment analysis for any company.") # User input company_name = st.text_input("Enter company name:", "Tesla") if st.button("Analyze"): with st.spinner("Analyzing news articles..."): try: # Process company data data = analyze_company_data(company_name) if not data["articles"]: st.error("No articles found for analysis.") return # Display overall sentiment st.subheader("Overall Sentiment Analysis") st.write(data["final_sentiment_analysis"]) # Create DataFrame for sentiment scores sentiment_df = pd.DataFrame(data["comparative_sentiment_score"]) # Display sentiment distribution by source st.subheader("Sentiment Distribution by Source") # Convert sentiment labels to numeric values for visualization sentiment_map = {'positive': 1, 'neutral': 0, 'negative': -1} numeric_df = sentiment_df.replace(sentiment_map) # Calculate sentiment distribution sentiment_dist = numeric_df.apply(lambda x: x.value_counts(normalize=True).to_dict()) # Create a new DataFrame for visualization viz_data = [] for source in sentiment_df.columns: dist = sentiment_dist[source] for sentiment, percentage in dist.items(): viz_data.append({ 'Source': source, 'Sentiment': sentiment, 'Percentage': percentage * 100 }) viz_df = pd.DataFrame(viz_data) # Create stacked bar chart fig = px.bar(viz_df, x='Source', y='Percentage', color='Sentiment', title='Sentiment Distribution by Source', barmode='stack') fig.update_layout( yaxis_title='Percentage', xaxis_title='News Source', legend_title='Sentiment' ) st.plotly_chart(fig) # Display fine-grained sentiment analysis st.subheader("Fine-grained Sentiment Analysis") # Create tabs for different fine-grained analyses tab1, tab2, tab3 = st.tabs(["Financial Sentiment", "Emotional Sentiment", "ESG Sentiment"]) with tab1: st.write("Financial Market Impact Analysis") financial_data = [] for article in data["articles"]: if "financial_sentiment" in article: financial_data.append({ "Article": article["title"], "Financial Impact": article["financial_sentiment"] }) if financial_data: st.dataframe(pd.DataFrame(financial_data)) else: st.info("Financial sentiment analysis not available for these articles.") with tab2: st.write("Emotional Sentiment Analysis") emotional_data = [] for article in data["articles"]: if "emotional_sentiment" in article: emotional_data.append({ "Article": article["title"], "Emotional Impact": article["emotional_sentiment"] }) if emotional_data: st.dataframe(pd.DataFrame(emotional_data)) else: st.info("Emotional sentiment analysis not available for these articles.") with tab3: st.write("ESG (Environmental, Social, Governance) Analysis") esg_data = [] for article in data["articles"]: if "esg_sentiment" in article: esg_data.append({ "Article": article["title"], "ESG Impact": article["esg_sentiment"] }) if esg_data: st.dataframe(pd.DataFrame(esg_data)) else: st.info("ESG sentiment analysis not available for these articles.") # Display articles with detailed sentiment analysis st.subheader("Recent Articles") for article in data["articles"]: with st.expander(article["title"]): st.write(f"**Source:** {article['source']}") st.write(f"**Summary:** {article['summary']}") st.write(f"**Overall Sentiment:** {article['sentiment']}") # Display fine-grained sentiment if available if "financial_sentiment" in article: st.write(f"**Financial Impact:** {article['financial_sentiment']}") if "emotional_sentiment" in article: st.write(f"**Emotional Impact:** {article['emotional_sentiment']}") if "esg_sentiment" in article: st.write(f"**ESG Impact:** {article['esg_sentiment']}") st.write(f"**URL:** [{article['url']}]({article['url']})") except Exception as e: st.error(f"Error analyzing company data: {str(e)}") print(f"Error: {str(e)}") if __name__ == "__main__": main()