GLAkavya commited on
Commit
10d721b
Β·
verified Β·
1 Parent(s): ba49331

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -129
app.py CHANGED
@@ -1,145 +1,127 @@
1
  import os
2
  import random
3
- import gradio as gr
 
4
  import plotly.express as px
5
- from transformers import pipeline
6
  import google.generativeai as genai
 
7
 
8
- # ----------------- CONFIG -----------------
9
- # Load Gemini API key from environment secrets
10
- GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
11
-
12
- if GEMINI_API_KEY:
13
- genai.configure(api_key=GEMINI_API_KEY)
14
- gemini_model = genai.GenerativeModel("gemini-1.5-flash")
15
- else:
16
- gemini_model = None
17
-
18
- # Hugging Face sentiment pipeline
19
  sentiment_pipeline = pipeline("sentiment-analysis")
20
 
21
- # ----------------- FUNCTIONS -----------------
22
- def generate_posts(hashtag: str, num_posts: int, use_gemini: bool):
 
23
  posts = []
24
- source = "huggingface"
25
-
26
- if use_gemini and gemini_model:
27
- prompt = f"Generate {num_posts} realistic social media posts about {hashtag}. Use emojis. Tone should vary (positive, negative, neutral)."
28
- try:
29
- response = gemini_model.generate_content(prompt)
30
- text = response.text
31
- posts = [line.strip("-β€’ ") for line in text.split("\n") if line.strip()][:num_posts]
32
- source = "gemini"
33
- except Exception as e:
34
- posts = [f"⚠️ Gemini API failed: {e}. Falling back to Hugging Face."]
35
- source = "huggingface"
36
-
37
- if not posts: # fallback
38
- template = [
39
- f"Not sure how I feel about {hashtag} πŸ€”",
40
- f"{hashtag} totally failed expectations 😠",
41
- f"People are talking about {hashtag} everywhere 🌍",
42
- f"{hashtag} campaign is the best thing this year πŸŽ‰",
43
  f"I'm disappointed with {hashtag} πŸ’”",
 
44
  f"Super excited about {hashtag} πŸ”₯",
 
 
45
  f"I love {hashtag}! It's amazing ❀️",
46
  ]
47
- posts = random.choices(template, k=num_posts)
48
 
49
  return posts, source
50
 
51
-
52
- def analyze_sentiments(hashtag, num_posts, visualization, use_gemini):
53
- num_posts = min(num_posts, 50) # cap at 50
54
-
55
- posts, source = generate_posts(hashtag, num_posts, use_gemini)
56
-
57
- results = []
58
- for post in posts:
59
- try:
60
- result = sentiment_pipeline(post[:512])[0]
61
- results.append((post, result["label"], round(result["score"], 2)))
62
- except Exception:
63
- results.append((post, "NEUTRAL", 0.5))
64
-
65
- # Visualization
66
- sentiments = [r[1] for r in results]
67
- fig = None
68
- if visualization == "Bar":
69
- fig = px.bar(x=sentiments, title=f"Sentiment Distribution for {hashtag}", labels={"x": "Sentiment", "y": "Count"})
70
- elif visualization == "Pie":
71
- fig = px.pie(names=sentiments, title=f"Sentiment Share for {hashtag}")
72
- elif visualization == "Line":
73
- fig = px.line(y=[1 if s == "POSITIVE" else -1 if s == "NEGATIVE" else 0 for s in sentiments],
74
- title=f"Sentiment Rolling Trend for {hashtag}")
75
-
76
- summary_text = f"βœ… Posts generated by **{source.upper()}**\nTotal Posts: {len(results)}"
77
- return results, fig, summary_text
78
-
79
- # ----------------- UI -----------------
80
- CUSTOM_CSS = """
81
- #col-left {
82
- background: rgba(25, 25, 25, 0.85);
83
- padding: 20px;
84
- border-radius: 16px;
85
- box-shadow: 0 0 20px rgba(0,0,0,0.4);
86
- animation: fadeInLeft 1s ease;
87
- }
88
- #col-right {
89
- background: rgba(15, 15, 15, 0.85);
90
- padding: 20px;
91
- border-radius: 16px;
92
- box-shadow: 0 0 20px rgba(0,0,0,0.4);
93
- animation: fadeInRight 1s ease;
94
- }
95
- .posts-table {
96
- max-height: 420px;
97
- overflow-y: auto;
98
- }
99
- @keyframes fadeInLeft {
100
- from {opacity: 0; transform: translateX(-30px);}
101
- to {opacity: 1; transform: translateX(0);}
102
- }
103
- @keyframes fadeInRight {
104
- from {opacity: 0; transform: translateX(30px);}
105
- to {opacity: 1; transform: translateX(0);}
106
- }
107
- button {
108
- transition: all 0.2s ease;
109
- }
110
- button:hover {
111
- transform: scale(1.05);
112
- box-shadow: 0 0 12px #ff6600;
113
- }
114
- """
115
-
116
- with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Soft()) as demo:
117
- gr.HTML("<h1 style='text-align:center; color:#FF6600;'>πŸš€ Social Media Sentiment Analyzer</h1>")
118
- gr.HTML("<p style='text-align:center;'>Stream posts β€’ Analyze moods β€’ Visualize trends</p>")
119
-
120
- with gr.Row():
121
- with gr.Column(elem_id="col-left"):
122
- hashtag = gr.Textbox(label="Enter Hashtag", value="#gla")
123
- num_posts = gr.Slider(5, 50, value=20, step=1, label="Number of Posts")
124
- visualization = gr.Dropdown(choices=["Bar", "Pie", "Line"], value="Bar", label="Choose Visualization")
125
- use_gemini = gr.Checkbox(label="Use Gemini Advanced Analysis", value=False)
126
- run_btn = gr.Button("πŸ” Run Analysis", variant="primary")
127
-
128
- with gr.Column(elem_id="col-right"):
129
- posts_table = gr.Dataframe(
130
- headers=["Post", "Sentiment", "Confidence"],
131
- interactive=False,
132
- elem_classes=["posts-table"]
133
- )
134
- plot_out = gr.Plot()
135
- summary = gr.Markdown()
136
-
137
- run_btn.click(
138
- analyze_sentiments,
139
- inputs=[hashtag, num_posts, visualization, use_gemini],
140
- outputs=[posts_table, plot_out, summary]
141
  )
142
-
143
- # ----------------- MAIN -----------------
144
- if __name__ == "__main__":
145
- demo.launch()
 
1
  import os
2
  import random
3
+ import streamlit as st
4
+ import pandas as pd
5
  import plotly.express as px
 
6
  import google.generativeai as genai
7
+ from transformers import pipeline
8
 
9
+ # ========== API KEYS ==========
10
+ genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
 
 
 
 
 
 
 
 
 
11
  sentiment_pipeline = pipeline("sentiment-analysis")
12
 
13
+ # ========== POST GENERATOR ==========
14
+ def generate_posts(hashtag, n=20):
15
+ """Try Gemini first, fallback to HuggingFace generated posts"""
16
  posts = []
17
+ source = "Gemini"
18
+
19
+ try:
20
+ prompt = f"Generate {n} realistic, diverse, short social media posts about {hashtag}. Use emojis."
21
+ response = genai.GenerativeModel("gemini-1.5-flash").generate_content(prompt)
22
+ text = response.text.strip().split("\n")
23
+ posts = [t for t in text if len(t.strip()) > 0][:n]
24
+ except Exception:
25
+ source = "HuggingFace"
26
+ base_posts = [
27
+ f"{hashtag} is the best thing ever πŸŽ‰",
 
 
 
 
 
 
 
 
28
  f"I'm disappointed with {hashtag} πŸ’”",
29
+ f"Not sure how I feel about {hashtag} πŸ€”",
30
  f"Super excited about {hashtag} πŸ”₯",
31
+ f"People are talking about {hashtag} everywhere 🌍",
32
+ f"{hashtag} totally failed expectations 😠",
33
  f"I love {hashtag}! It's amazing ❀️",
34
  ]
35
+ posts = random.choices(base_posts, k=n)
36
 
37
  return posts, source
38
 
39
+ # ========== SENTIMENT ANALYSIS ==========
40
+ def analyze_posts(posts):
41
+ results = sentiment_pipeline(posts)
42
+ data = []
43
+ for post, res in zip(posts, results):
44
+ data.append({
45
+ "Post": post,
46
+ "Sentiment": res["label"],
47
+ "Confidence": round(res["score"], 2)
48
+ })
49
+ return pd.DataFrame(data)
50
+
51
+ # ========== STREAMLIT UI ==========
52
+ st.set_page_config(
53
+ page_title="AI Sentiment Analyzer",
54
+ page_icon="πŸ“Š",
55
+ layout="wide",
56
+ initial_sidebar_state="expanded"
57
+ )
58
+
59
+ st.markdown(
60
+ """
61
+ <style>
62
+ body {
63
+ background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
64
+ color: white;
65
+ }
66
+ .stButton button {
67
+ background: linear-gradient(45deg, #ff6b6b, #f7b733);
68
+ color: white;
69
+ font-weight: bold;
70
+ border-radius: 12px;
71
+ padding: 10px 20px;
72
+ transition: 0.3s;
73
+ }
74
+ .stButton button:hover {
75
+ transform: scale(1.05);
76
+ background: linear-gradient(45deg, #36d1dc, #5b86e5);
77
+ }
78
+ .moving {
79
+ animation: float 3s ease-in-out infinite;
80
+ }
81
+ @keyframes float {
82
+ 0% { transform: translatey(0px); }
83
+ 50% { transform: translatey(-10px); }
84
+ 100% { transform: translatey(0px); }
85
+ }
86
+ </style>
87
+ """,
88
+ unsafe_allow_html=True
89
+ )
90
+
91
+ st.title("πŸš€ Social Media Sentiment Analyzer")
92
+ st.markdown("### Stream posts β€’ Analyze moods β€’ Visualize trends with animations")
93
+
94
+ # Sidebar
95
+ st.sidebar.header("βš™οΈ Controls")
96
+ hashtag = st.sidebar.text_input("Enter Hashtag", "#gla")
97
+ num_posts = st.sidebar.slider("Number of Posts", 5, 50, 20)
98
+ vis_type = st.sidebar.selectbox("Choose Visualization", ["Bar", "Pie", "Line"])
99
+
100
+ if st.sidebar.button("πŸ” Run Analysis"):
101
+ with st.spinner("Generating posts and analyzing sentiments..."):
102
+ posts, source = generate_posts(hashtag, num_posts)
103
+ df = analyze_posts(posts)
104
+
105
+ st.success(f"βœ… Posts generated by **{source}** | Total: {len(posts)}")
106
+
107
+ st.dataframe(df, use_container_width=True)
108
+
109
+ # ===== VISUALIZATIONS =====
110
+ if vis_type == "Bar":
111
+ fig = px.bar(df, x="Sentiment", color="Sentiment", title=f"Sentiment Distribution for {hashtag}", animation_frame=None)
112
+ elif vis_type == "Pie":
113
+ fig = px.pie(df, names="Sentiment", title=f"Sentiment Share for {hashtag}", hole=0.4)
114
+ else:
115
+ fig = px.line(df, y="Confidence", title=f"Confidence Trend for {hashtag}")
116
+
117
+ st.plotly_chart(fig, use_container_width=True)
118
+
119
+ # ===== Moving 3D-like floating animation =====
120
+ st.markdown(
121
+ f"""
122
+ <div class="moving" style="font-size:24px; text-align:center; margin-top:30px;">
123
+ 🌍 πŸ”₯ ❀️ πŸŽ‰ Trending Vibes around <b>{hashtag}</b>
124
+ </div>
125
+ """,
126
+ unsafe_allow_html=True
 
 
127
  )