Sirapatrwan commited on
Commit
940ba87
·
verified ·
1 Parent(s): 9982df9

Upload api.py

Browse files
Files changed (1) hide show
  1. api.py +129 -0
api.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ from utils import fetch_news, analyze_sentiment, extract_topics, generate_tts
4
+ import random
5
+
6
+ # Set up the FastAPI server with a name and description
7
+ app = FastAPI(title="News Sentiment API", description="Analyze news sentiment for companies")
8
+
9
+ class CompanyInput(BaseModel):
10
+ """Simple model to validate incoming company name."""
11
+ company: str
12
+
13
+ @app.post("/analyze")
14
+ async def analyze_company(input: CompanyInput):
15
+ """Take a company name and return its news sentiment analysis."""
16
+ company = input.company
17
+ articles_data = fetch_news(company)
18
+ if not articles_data:
19
+ return {"error": f"No articles found for {company}. Check logs for details."}
20
+
21
+ articles = []
22
+ sentiments = {"Positive": 0, "Negative": 0, "Neutral": 0}
23
+ positive_articles = []
24
+ negative_articles = []
25
+ neutral_articles = []
26
+
27
+ for article in articles_data:
28
+ summary = article["summary"].strip() or article["title"].split(" - ")[0].strip()
29
+ source = article["title"].split(" - ")[-1].strip() if " - " in article["title"] else ""
30
+ if source in summary:
31
+ summary = summary.replace(source, "").strip()
32
+ summary = f"{summary.rstrip(' -')} - {source}"
33
+
34
+ sentiment = analyze_sentiment(summary)
35
+ topics = extract_topics(summary)
36
+ sentiments[sentiment] += 1
37
+
38
+ title = article["title"].split(" - ")[0].strip()
39
+ if sentiment == "Positive":
40
+ positive_articles.append(title)
41
+ elif sentiment == "Negative":
42
+ negative_articles.append(title)
43
+ else:
44
+ neutral_articles.append(title)
45
+
46
+ articles.append({
47
+ "Title": article["title"],
48
+ "Summary": summary,
49
+ "Sentiment": sentiment,
50
+ "Topics": topics,
51
+ "Link": article["link"],
52
+ "PubDate": article["pub_date"]
53
+ })
54
+
55
+ detailed_comparisons = [f"- News {i + 1} {article['Sentiment'].lower()}ly discusses {', '.join(article['Topics'])}"
56
+ for i, article in enumerate(articles)]
57
+ dominant_sentiment = max(sentiments, key=sentiments.get)
58
+ trends = f"{company} News Trends: {dominant_sentiment}"
59
+
60
+ total_articles = sum(sentiments.values())
61
+ sentiment_count = f"{sentiments['Positive']} positive, {sentiments['Negative']} negative, {sentiments['Neutral']} neutral"
62
+
63
+ intro_phrases = [
64
+ f"Spanning {total_articles} recent reports, the narrative surrounding {company} tilts {dominant_sentiment.lower()}, with {sentiment_count}.",
65
+ f"Across {total_articles} articles in recent coverage, {company}’s story emerges as predominantly {dominant_sentiment.lower()}, reflecting {sentiment_count}.",
66
+ f"Drawing from {total_articles} latest publications, {company}’s news landscape leans {dominant_sentiment.lower()}, underscored by {sentiment_count}."
67
+ ]
68
+ positive_phrases = [
69
+ f"With {len(positive_articles)} favorable accounts, {company} demonstrates notable progress, exemplified by '{random.choice(positive_articles) if positive_articles else 'no specific examples available'}'.",
70
+ f"Boasting {len(positive_articles)} positive developments, {company} showcases strength, as evidenced in '{random.choice(positive_articles) if positive_articles else 'no notable instances'}'.",
71
+ f"Highlighted by {len(positive_articles)} encouraging reports, {company} is forging ahead, with '{random.choice(positive_articles) if positive_articles else 'no standout reports'}' standing out."
72
+ ]
73
+ negative_phrases = [
74
+ f"However, {len(negative_articles)} troubling narratives raise concerns, including '{random.choice(negative_articles) if negative_articles else 'no specific concerns noted'}'.",
75
+ f"Yet, {len(negative_articles)} adverse reports signal challenges, such as '{random.choice(negative_articles) if negative_articles else 'no highlighted issues'}'.",
76
+ f"Nevertheless, {len(negative_articles)} concerning stories cast a shadow, notably '{random.choice(negative_articles) if negative_articles else 'no notable setbacks'}'."
77
+ ]
78
+ neutral_phrases = [
79
+ f"Additionally, {len(neutral_articles)} impartial updates provide context, such as '{random.choice(neutral_articles) if neutral_articles else 'no neutral updates available'}'.",
80
+ f"Meanwhile, {len(neutral_articles)} balanced accounts offer insight, including '{random.choice(neutral_articles) if neutral_articles else 'no balanced reports'}'.",
81
+ f"Furthermore, {len(neutral_articles)} objective pieces contribute details, like '{random.choice(neutral_articles) if neutral_articles else 'no objective details'}'."
82
+ ]
83
+ outlook_phrases_positive = [
84
+ f"In summary, {company} appears poised for a favorable trajectory.",
85
+ f"All told, {company} stands on the cusp of a promising future.",
86
+ f"Ultimately, {company} is positioned for an optimistic course ahead."
87
+ ]
88
+ outlook_phrases_negative = [
89
+ f"In conclusion, {company} confronts a challenging path forward.",
90
+ f"Overall, {company} navigates a formidable road ahead.",
91
+ f"To conclude, {company} faces a demanding horizon."
92
+ ]
93
+ outlook_phrases_mixed = [
94
+ f"In the final analysis, {company} balances opportunity and uncertainty.",
95
+ f"On balance, {company} presents a complex outlook moving forward.",
96
+ f"Ultimately, {company} reflects a blend of prospects and hurdles."
97
+ ]
98
+
99
+ final_text = random.choice(intro_phrases) + " "
100
+ if positive_articles:
101
+ final_text += random.choice(positive_phrases) + " "
102
+ if negative_articles:
103
+ final_text += random.choice(negative_phrases) + " "
104
+ if neutral_articles:
105
+ final_text += random.choice(neutral_phrases) + " "
106
+ if sentiments["Positive"] > sentiments["Negative"]:
107
+ final_text += random.choice(outlook_phrases_positive)
108
+ elif sentiments["Negative"] > sentiments["Positive"]:
109
+ final_text += random.choice(outlook_phrases_negative)
110
+ else:
111
+ final_text += random.choice(outlook_phrases_mixed)
112
+
113
+ print(f"Generated dynamic final sentiment for {company}: {final_text}")
114
+
115
+ return {
116
+ "Company": company,
117
+ "Articles": articles,
118
+ "Comparative Sentiment Score": {
119
+ "Sentiment Distribution": f"Positive: {sentiments['Positive']}, Negative: {sentiments['Negative']}, Neutral: {sentiments['Neutral']}",
120
+ "Trends": trends,
121
+ "Detailed Comparisons": "\n".join(detailed_comparisons)
122
+ },
123
+ "Final Sentiment Analysis": final_text.strip(),
124
+ "Audio": None
125
+ }
126
+
127
+ if __name__ == "__main__":
128
+ import uvicorn
129
+ uvicorn.run(app, host="0.0.0.0", port=8000) # Start the API server on port 8000