GLAkavya commited on
Commit
6ca8b23
Β·
verified Β·
1 Parent(s): 0928dc0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +145 -102
app.py CHANGED
@@ -1,120 +1,163 @@
1
  import gradio as gr
2
- from transformers import pipeline
3
- import pandas as pd
4
  import random
5
- import time
6
  import plotly.express as px
7
- import requests
8
- import os
 
9
 
10
- # ---------------------------
11
- # Load Hugging Face sentiment model
12
- # ---------------------------
13
  sentiment_model = pipeline("sentiment-analysis")
14
 
15
- # ---------------------------
16
- # Gemini API Config
17
- # ---------------------------
18
- GEMINI_API_KEY = os.getenv("GOOGLE_API_KEY")
19
-
20
- def gemini_sentiment(text):
21
- """Use Gemini API for sentiment analysis"""
22
- if not GEMINI_API_KEY:
23
- return {"label": "NEUTRAL", "score": 0.0}
24
-
25
- url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent"
26
- headers = {"Content-Type": "application/json", "X-goog-api-key": GEMINI_API_KEY}
27
- payload = {
28
- "contents": [{"parts": [{"text": f"Classify sentiment of this text as Positive, Negative or Neutral:\n\n{text}"}]}]
29
- }
30
- resp = requests.post(url, headers=headers, json=payload)
31
- if resp.status_code == 200:
32
- ai_text = resp.json()["candidates"][0]["content"]["parts"][0]["text"].strip().lower()
33
- if "positive" in ai_text:
34
- return {"label": "POSITIVE", "score": 0.9}
35
- elif "negative" in ai_text:
36
- return {"label": "NEGATIVE", "score": 0.9}
37
- else:
38
- return {"label": "NEUTRAL", "score": 0.5}
39
- return {"label": "NEUTRAL", "score": 0.0}
40
-
41
- # ---------------------------
42
- # Mock social posts generator
43
- # ---------------------------
44
- def fetch_posts(hashtag, n=20):
45
- samples = [
46
- f"I love {hashtag}! It's amazing ❀️",
47
- f"{hashtag} is the worst thing ever 😑",
48
- f"Not sure how I feel about {hashtag} πŸ€”",
49
- f"Super excited about {hashtag} πŸ”₯",
50
- f"{hashtag} totally failed expectations 😞",
51
- f"People are talking about {hashtag} everywhere 🌍",
52
- f"I'm disappointed with {hashtag} πŸ’”",
53
- f"{hashtag} campaign is the best thing this year πŸŽ‰",
54
- ]
55
- return [random.choice(samples) for _ in range(n)]
56
-
57
- # ---------------------------
58
- # Analyzer function
59
- # ---------------------------
60
- def analyze_hashtag(hashtag, n_posts=20, chart_type="Bar", use_gemini=False):
61
- posts = fetch_posts(hashtag, n_posts)
 
 
 
62
  results = []
63
 
64
- for p in posts:
65
- if use_gemini:
66
- result = gemini_sentiment(p)
67
- else:
68
- result = sentiment_model(p)[0]
69
- results.append({"Post": p, "Sentiment": result["label"], "Confidence": round(result["score"], 2)})
70
- time.sleep(0.05) # simulate streaming
71
-
72
- df = pd.DataFrame(results)
73
-
74
- # Count distribution
75
- sentiment_counts = df["Sentiment"].value_counts().reset_index()
76
- sentiment_counts.columns = ["Sentiment", "Count"]
77
-
78
- # Plotly Graph
79
- if chart_type == "Bar":
80
- fig = px.bar(sentiment_counts, x="Sentiment", y="Count", color="Sentiment",
81
- title=f"Sentiment Distribution for {hashtag}")
82
- elif chart_type == "Pie":
83
- fig = px.pie(sentiment_counts, names="Sentiment", values="Count",
84
- title=f"Sentiment Share for {hashtag}")
85
- else: # Line chart (simulate rolling trend)
86
- fig = px.line(sentiment_counts, x="Sentiment", y="Count", markers=True,
87
- title=f"Sentiment Rolling Trend for {hashtag}")
88
-
89
- return df, fig
90
-
91
- # ---------------------------
92
- # Gradio UI
93
- # ---------------------------
94
- with gr.Blocks(css=".footer {text-align:center; font-size:16px; color:#ff66cc; font-weight:bold; animation: glow 1.5s ease-in-out infinite alternate;} @keyframes glow { from { text-shadow: 0 0 10px #ff66cc; } to { text-shadow: 0 0 20px #ff33aa; }}") as demo:
95
- gr.Markdown(
96
- """
97
- <div style='text-align:center; padding: 20px; background: linear-gradient(90deg, #1e3c72, #2a5298); color: white; border-radius: 12px;'>
98
- <h1>πŸ“Š Social Media Sentiment Analyzer</h1>
99
- <p>Stream posts β€’ Analyze moods β€’ Visualize trends</p>
100
- </div>
101
  """
102
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  with gr.Row():
105
  with gr.Column(scale=1):
106
- hashtag = gr.Textbox(label="Enter Hashtag", placeholder="#YourCampaign")
107
- n_posts = gr.Slider(5, 50, step=5, value=20, label="Number of Posts")
108
- chart_type = gr.Dropdown(["Bar", "Pie", "Line"], value="Bar", label="Choose Visualization")
109
- use_gemini = gr.Checkbox(label="Use Gemini Advanced Analysis", value=False)
110
- btn = gr.Button("πŸš€ Run Analysis", variant="primary")
111
 
112
  with gr.Column(scale=2):
113
- output_table = gr.Dataframe(label="Posts & Sentiments", wrap=True)
114
  output_plot = gr.Plot(label="Visualization")
115
 
116
- btn.click(fn=analyze_hashtag, inputs=[hashtag, n_posts, chart_type, use_gemini], outputs=[output_table, output_plot])
117
-
118
- gr.HTML("<div class='footer'>✨ Made with πŸ’œ by Kavya</div>")
119
 
120
  demo.launch()
 
1
  import gradio as gr
 
 
2
  import random
 
3
  import plotly.express as px
4
+ import pandas as pd
5
+ from transformers import pipeline
6
+ import google.generativeai as genai
7
 
8
+ # ------------------------------
9
+ # Setup HuggingFace Transformer
10
+ # ------------------------------
11
  sentiment_model = pipeline("sentiment-analysis")
12
 
13
+ # ------------------------------
14
+ # Setup Gemini (Google AI Studio)
15
+ # ------------------------------
16
+ GEMINI_KEY = "YOUR_GEMINI_API_KEY"
17
+ genai.configure(api_key=GEMINI_KEY)
18
+
19
+ # Helper to call Gemini
20
+ def gemini_generate(prompt):
21
+ model = genai.GenerativeModel("gemini-1.5-flash")
22
+ response = model.generate_content(prompt)
23
+ return response.text
24
+
25
+ # ------------------------------
26
+ # Fake post generator with Gemini
27
+ # ------------------------------
28
+ def generate_posts(hashtag, n_posts, use_gemini=False):
29
+ posts = []
30
+
31
+ if use_gemini:
32
+ prompt = f"""
33
+ Generate {n_posts} short social media posts about "{hashtag}".
34
+ Posts must be realistic, 1-2 sentences each, like from Twitter.
35
+ Ensure balanced sentiment: mostly realistic negatives if topic is bad,
36
+ some neutral, and very few positive.
37
+ Return only the posts as a numbered list.
38
+ """
39
+ try:
40
+ text = gemini_generate(prompt)
41
+ posts = [line.split(". ",1)[-1] for line in text.split("\n") if line.strip()]
42
+ except Exception as e:
43
+ posts = [f"Error generating with Gemini: {e}"]
44
+ else:
45
+ sample_posts = [
46
+ f"{hashtag} totally failed expectations 😞",
47
+ f"Not sure how I feel about {hashtag} πŸ€”",
48
+ f"{hashtag} is the worst thing ever 😑",
49
+ f"Super excited about {hashtag} πŸ”₯",
50
+ f"People are talking about {hashtag} everywhere 🌍",
51
+ f"{hashtag} campaign is the best thing this year πŸŽ‰",
52
+ f"I'm disappointed with {hashtag} πŸ’”",
53
+ f"I love {hashtag}! It's amazing ❀️"
54
+ ]
55
+ posts = random.choices(sample_posts, k=n_posts)
56
+
57
+ return posts[:n_posts]
58
+
59
+ # ------------------------------
60
+ # Sentiment Analysis
61
+ # ------------------------------
62
+ def analyze_sentiment(posts, use_gemini=False):
63
  results = []
64
 
65
+ if use_gemini:
66
+ # Limit Gemini analysis to 10 posts (quota safe)
67
+ subset = posts[:10]
68
+ prompt = f"""
69
+ Analyze the sentiment of the following posts:
70
+ {subset}
71
+ Respond as JSON list with: post, sentiment (POSITIVE/NEGATIVE/NEUTRAL), confidence (0-1).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  """
73
+ try:
74
+ text = gemini_generate(prompt)
75
+ # naive parse: fallback to HF if parsing fails
76
+ if "POSITIVE" in text or "NEGATIVE" in text:
77
+ for line in text.split("\n"):
78
+ if line.strip():
79
+ if "POSITIVE" in line:
80
+ results.append({"post": line, "sentiment": "POSITIVE", "confidence": 1.0})
81
+ elif "NEGATIVE" in line:
82
+ results.append({"post": line, "sentiment": "NEGATIVE", "confidence": 1.0})
83
+ elif "NEUTRAL" in line:
84
+ results.append({"post": line, "sentiment": "NEUTRAL", "confidence": 1.0})
85
+ else:
86
+ raise Exception("Parsing failed")
87
+ except:
88
+ # fallback to HF
89
+ results = [{"post": p, **sentiment_model(p)[0]} for p in posts]
90
+
91
+ else:
92
+ results = [{"post": p, **sentiment_model(p)[0]} for p in posts]
93
+
94
+ # Format uniform
95
+ clean = []
96
+ for r in results:
97
+ label = r["label"] if "label" in r else r["sentiment"]
98
+ score = r["score"] if "score" in r else r.get("confidence", 0.8)
99
+ clean.append({
100
+ "Post": r["post"],
101
+ "Sentiment": label.upper(),
102
+ "Confidence": round(score, 2)
103
+ })
104
+ return clean
105
+
106
+ # ------------------------------
107
+ # Visualization
108
+ # ------------------------------
109
+ def create_viz(data, viz_type, hashtag):
110
+ df = pd.DataFrame(data)
111
+
112
+ if viz_type == "Bar":
113
+ fig = px.bar(df, x="Sentiment", title=f"Sentiment Distribution for {hashtag}")
114
+ elif viz_type == "Pie":
115
+ fig = px.pie(df, names="Sentiment", title=f"Sentiment Share for {hashtag}")
116
+ elif viz_type == "Line":
117
+ fig = px.line(df, y="Confidence", title=f"Sentiment Confidence Trend for {hashtag}")
118
+ elif viz_type == "Area":
119
+ fig = px.area(df, y="Confidence", title=f"Sentiment Rolling Area for {hashtag}")
120
+ else:
121
+ fig = px.histogram(df, x="Sentiment", title=f"Sentiment Histogram for {hashtag}")
122
+
123
+ return fig
124
+
125
+ # ------------------------------
126
+ # Main App Function
127
+ # ------------------------------
128
+ def run_analysis(hashtag, n_posts, viz_type, use_gemini):
129
+ posts = generate_posts(hashtag, n_posts, use_gemini)
130
+ data = analyze_sentiment(posts, use_gemini)
131
+ fig = create_viz(data, viz_type, hashtag)
132
+ return pd.DataFrame(data), fig
133
+
134
+ # ------------------------------
135
+ # Gradio UI
136
+ # ------------------------------
137
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="purple")) as demo:
138
+ gr.HTML("""
139
+ <div style="text-align:center; padding:20px; color:white;">
140
+ <h1 style="font-size:40px; background: linear-gradient(90deg, #ff8c00, #e94057, #8a2be2);
141
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
142
+ πŸš€ Social Media Sentiment Analyzer</h1>
143
+ <p style="font-size:18px;">Stream posts β€’ Analyze moods β€’ Visualize trends</p>
144
+ </div>
145
+ """)
146
 
147
  with gr.Row():
148
  with gr.Column(scale=1):
149
+ hashtag = gr.Textbox(label="Enter Hashtag", placeholder="#gla")
150
+ n_posts = gr.Slider(5, 50, step=1, value=20, label="Number of Posts")
151
+ viz_type = gr.Dropdown(["Bar", "Pie", "Line", "Area"], value="Bar", label="Choose Visualization")
152
+ use_gemini = gr.Checkbox(label="Use Gemini Advanced Analysis")
153
+ run_btn = gr.Button("πŸš€ Run Analysis", variant="primary")
154
 
155
  with gr.Column(scale=2):
156
+ output_table = gr.Dataframe(headers=["Post", "Sentiment", "Confidence"], label="Posts & Sentiments")
157
  output_plot = gr.Plot(label="Visualization")
158
 
159
+ run_btn.click(fn=run_analysis,
160
+ inputs=[hashtag, n_posts, viz_type, use_gemini],
161
+ outputs=[output_table, output_plot])
162
 
163
  demo.launch()