proKBD commited on
Commit
71f0750
·
verified ·
1 Parent(s): ada2f0f

Update api.py

Browse files
Files changed (1) hide show
  1. api.py +182 -72
api.py CHANGED
@@ -1,72 +1,182 @@
1
- """FastAPI backend for the News Summarization application."""
2
-
3
- from fastapi import FastAPI, HTTPException
4
- from fastapi.staticfiles import StaticFiles
5
- from pydantic import BaseModel
6
- from typing import List, Dict, Any
7
- import uvicorn
8
- from utils import NewsExtractor, SentimentAnalyzer, TextToSpeechConverter, ComparativeAnalyzer
9
- import os
10
- from config import API_PORT, AUDIO_OUTPUT_DIR
11
- import time
12
-
13
- app = FastAPI(title="News Summarization API")
14
-
15
- # Mount static directory for audio files
16
- os.makedirs(AUDIO_OUTPUT_DIR, exist_ok=True)
17
- app.mount("/audio", StaticFiles(directory=AUDIO_OUTPUT_DIR), name="audio")
18
-
19
- # Initialize components
20
- news_extractor = NewsExtractor()
21
- sentiment_analyzer = SentimentAnalyzer()
22
- tts_converter = TextToSpeechConverter()
23
- comparative_analyzer = ComparativeAnalyzer()
24
-
25
- class CompanyRequest(BaseModel):
26
- name: str
27
-
28
- class AnalysisResponse(BaseModel):
29
- company: str
30
- articles: List[Dict[str, Any]]
31
- comparative_sentiment_score: Dict[str, Any]
32
- final_sentiment_analysis: str
33
- audio_url: str = None
34
-
35
- @app.post("/api/analyze", response_model=AnalysisResponse)
36
- async def analyze_company(request: CompanyRequest):
37
- """Analyze news articles for a given company."""
38
- try:
39
- # Extract news articles
40
- articles = news_extractor.search_news(request.name)
41
- if not articles:
42
- raise HTTPException(status_code=404, detail="No articles found for the company")
43
-
44
- # Analyze each article
45
- analyzed_articles = []
46
- for article in articles:
47
- analysis = sentiment_analyzer.analyze_article(article)
48
- # Add company name to each article
49
- analysis['company'] = request.name
50
- analyzed_articles.append(analysis)
51
-
52
- # Perform comparative analysis
53
- comparison = comparative_analyzer.analyze_coverage(analyzed_articles, company_name=request.name)
54
- final_analysis = comparison["final_sentiment"]
55
-
56
- # Generate Hindi audio for final analysis
57
- audio_filename = f"{request.name.lower().replace(' ', '_')}_{int(time.time())}"
58
- audio_path = tts_converter.generate_audio(final_analysis, audio_filename)
59
- audio_url = f"/audio/{os.path.basename(audio_path)}"
60
-
61
- return {
62
- "company": request.name,
63
- "articles": analyzed_articles,
64
- "comparative_sentiment_score": comparison,
65
- "final_sentiment_analysis": final_analysis,
66
- "audio_url": audio_url
67
- }
68
- except Exception as e:
69
- raise HTTPException(status_code=500, detail=str(e))
70
-
71
- if __name__ == "__main__":
72
- uvicorn.run(app, host="0.0.0.0", port=API_PORT)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Streamlit frontend for the News Summarization application."""
2
+
3
+ import streamlit as st
4
+ import pandas as pd
5
+ import json
6
+ import os
7
+ import plotly.express as px
8
+ import altair as alt
9
+ from utils import analyze_company_data # Import the analysis function directly
10
+
11
+ # Set page config
12
+ st.set_page_config(
13
+ page_title="News Summarization App",
14
+ page_icon="📰",
15
+ layout="wide"
16
+ )
17
+
18
+ # Show loading message
19
+ with st.spinner("Initializing the application... Please wait while we load the models."):
20
+ # Initialize components
21
+ try:
22
+ from utils import NewsExtractor, SentimentAnalyzer, TextSummarizer, TextToSpeechConverter
23
+ st.success("Application initialized successfully!")
24
+ except Exception as e:
25
+ st.error(f"Error initializing application: {str(e)}")
26
+ st.info("Please try refreshing the page.")
27
+
28
+ def process_company(company_name):
29
+ """Process company data directly."""
30
+ try:
31
+ # Call the analysis function directly from utils
32
+ data = analyze_company_data(company_name)
33
+
34
+ # Generate audio if needed
35
+ if 'summary' in data:
36
+ from gtts import gTTS
37
+ tts = gTTS(text=data['summary'], lang='en')
38
+ audio_path = os.path.join('audio_output', f'{company_name}_summary.mp3')
39
+ os.makedirs('audio_output', exist_ok=True)
40
+ tts.save(audio_path)
41
+ data['audio_path'] = audio_path
42
+
43
+ return data
44
+ except Exception as e:
45
+ st.error(f"Error processing company: {str(e)}")
46
+ return {"articles": [], "comparative_sentiment_score": {}, "final_sentiment_analysis": "", "audio_path": None}
47
+
48
+ def main():
49
+ st.title("News Summarization App")
50
+ st.write("Analyze news articles and get sentiment analysis for any company.")
51
+
52
+ # User input
53
+ company_name = st.text_input("Enter company name:", "Tesla")
54
+
55
+ if st.button("Analyze"):
56
+ with st.spinner("Analyzing news articles..."):
57
+ try:
58
+ # Process company data
59
+ data = analyze_company_data(company_name)
60
+
61
+ if not data["articles"]:
62
+ st.error("No articles found for analysis.")
63
+ return
64
+
65
+ # Display overall sentiment
66
+ st.subheader("Overall Sentiment Analysis")
67
+ st.write(data["final_sentiment_analysis"])
68
+
69
+ # Create DataFrame for sentiment scores
70
+ sentiment_df = pd.DataFrame(data["comparative_sentiment_score"])
71
+
72
+ # Display sentiment distribution by source
73
+ st.subheader("Sentiment Distribution by Source")
74
+
75
+ # Convert sentiment labels to numeric values for visualization
76
+ sentiment_map = {'positive': 1, 'neutral': 0, 'negative': -1}
77
+ numeric_df = sentiment_df.replace(sentiment_map)
78
+
79
+ # Calculate sentiment distribution
80
+ sentiment_dist = numeric_df.apply(lambda x: x.value_counts(normalize=True).to_dict())
81
+
82
+ # Create a new DataFrame for visualization
83
+ viz_data = []
84
+ for source in sentiment_df.columns:
85
+ dist = sentiment_dist[source]
86
+ for sentiment, percentage in dist.items():
87
+ viz_data.append({
88
+ 'Source': source,
89
+ 'Sentiment': sentiment,
90
+ 'Percentage': percentage * 100
91
+ })
92
+
93
+ viz_df = pd.DataFrame(viz_data)
94
+
95
+ # Create stacked bar chart
96
+ fig = px.bar(viz_df,
97
+ x='Source',
98
+ y='Percentage',
99
+ color='Sentiment',
100
+ title='Sentiment Distribution by Source',
101
+ barmode='stack')
102
+
103
+ fig.update_layout(
104
+ yaxis_title='Percentage',
105
+ xaxis_title='News Source',
106
+ legend_title='Sentiment'
107
+ )
108
+
109
+ st.plotly_chart(fig)
110
+
111
+ # Display fine-grained sentiment analysis
112
+ st.subheader("Fine-grained Sentiment Analysis")
113
+
114
+ # Create tabs for different fine-grained analyses
115
+ tab1, tab2, tab3 = st.tabs(["Financial Sentiment", "Emotional Sentiment", "ESG Sentiment"])
116
+
117
+ with tab1:
118
+ st.write("Financial Market Impact Analysis")
119
+ financial_data = []
120
+ for article in data["articles"]:
121
+ if "financial_sentiment" in article:
122
+ financial_data.append({
123
+ "Article": article["title"],
124
+ "Financial Impact": article["financial_sentiment"]
125
+ })
126
+ if financial_data:
127
+ st.dataframe(pd.DataFrame(financial_data))
128
+ else:
129
+ st.info("Financial sentiment analysis not available for these articles.")
130
+
131
+ with tab2:
132
+ st.write("Emotional Sentiment Analysis")
133
+ emotional_data = []
134
+ for article in data["articles"]:
135
+ if "emotional_sentiment" in article:
136
+ emotional_data.append({
137
+ "Article": article["title"],
138
+ "Emotional Impact": article["emotional_sentiment"]
139
+ })
140
+ if emotional_data:
141
+ st.dataframe(pd.DataFrame(emotional_data))
142
+ else:
143
+ st.info("Emotional sentiment analysis not available for these articles.")
144
+
145
+ with tab3:
146
+ st.write("ESG (Environmental, Social, Governance) Analysis")
147
+ esg_data = []
148
+ for article in data["articles"]:
149
+ if "esg_sentiment" in article:
150
+ esg_data.append({
151
+ "Article": article["title"],
152
+ "ESG Impact": article["esg_sentiment"]
153
+ })
154
+ if esg_data:
155
+ st.dataframe(pd.DataFrame(esg_data))
156
+ else:
157
+ st.info("ESG sentiment analysis not available for these articles.")
158
+
159
+ # Display articles with detailed sentiment analysis
160
+ st.subheader("Recent Articles")
161
+ for article in data["articles"]:
162
+ with st.expander(article["title"]):
163
+ st.write(f"**Source:** {article['source']}")
164
+ st.write(f"**Summary:** {article['summary']}")
165
+ st.write(f"**Overall Sentiment:** {article['sentiment']}")
166
+
167
+ # Display fine-grained sentiment if available
168
+ if "financial_sentiment" in article:
169
+ st.write(f"**Financial Impact:** {article['financial_sentiment']}")
170
+ if "emotional_sentiment" in article:
171
+ st.write(f"**Emotional Impact:** {article['emotional_sentiment']}")
172
+ if "esg_sentiment" in article:
173
+ st.write(f"**ESG Impact:** {article['esg_sentiment']}")
174
+
175
+ st.write(f"**URL:** [{article['url']}]({article['url']})")
176
+
177
+ except Exception as e:
178
+ st.error(f"Error analyzing company data: {str(e)}")
179
+ print(f"Error: {str(e)}")
180
+
181
+ if __name__ == "__main__":
182
+ main()