DevNumb commited on
Commit
fde3c7b
ยท
verified ยท
1 Parent(s): f842ed2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +181 -113
app.py CHANGED
@@ -8,18 +8,28 @@ from datetime import datetime
8
  import plotly.express as px
9
  import plotly.graph_objects as go
10
  from plotly.subplots import make_subplots
 
11
 
12
  class AdvancedSentimentAnalyzer:
13
  def __init__(self, model_name="tabularisai/multilingual-sentiment-analysis"):
 
14
  self.model_name = model_name
15
- self.tokenizer = AutoTokenizer.from_pretrained(model_name)
16
- self.model = AutoModelForSequenceClassification.from_pretrained(model_name)
17
- self.classifier = pipeline(
18
- "text-classification",
19
- model=self.model,
20
- tokenizer=self.tokenizer,
21
- return_all_scores=True
22
- )
 
 
 
 
 
 
 
 
23
 
24
  self.sentiment_map = {
25
  0: "Very Negative",
@@ -38,24 +48,29 @@ class AdvancedSentimentAnalyzer:
38
  }
39
 
40
  self.language_detection_keywords = {
41
- 'english': ['the', 'and', 'is', 'in', 'to'],
42
- 'spanish': ['el', 'la', 'de', 'que', 'y'],
43
- 'french': ['le', 'la', 'de', 'et', 'que'],
44
- 'german': ['der', 'die', 'das', 'und', 'zu'],
45
- 'italian': ['il', 'la', 'di', 'e', 'che'],
46
- 'portuguese': ['o', 'a', 'de', 'e', 'que'],
47
- 'dutch': ['de', 'het', 'en', 'van', 'te'],
48
- 'russian': ['ะธ', 'ะฒ', 'ะฝะต', 'ะฝะฐ', 'ั'],
49
- 'chinese': ['็š„', 'ๆ˜ฏ', 'ๅœจ', 'ไบ†', 'ๆœ‰'],
50
- 'japanese': ['ใฎ', 'ใซ', 'ใฏ', 'ใ‚’', 'ใŸ'],
51
- 'korean': ['์ด', '์—', '๋Š”', '์„', '๋‹ค'],
52
- 'arabic': ['ุงู„', 'ููŠ', 'ู…ู†', 'ุนู„ู‰', 'ุฃู†'],
53
- 'hindi': ['เค•เฅ€', 'เคธเฅ‡', 'เคนเฅˆ', 'เค”เคฐ', 'เค•เฅ‡'],
54
- 'turkish': ['ve', 'bir', 'bu', 'ile', 'iรงin']
55
  }
56
-
 
 
57
  def detect_language(self, text):
58
  """Simple language detection based on common words"""
 
 
 
59
  text_lower = text.lower()
60
  scores = {}
61
 
@@ -63,20 +78,57 @@ class AdvancedSentimentAnalyzer:
63
  score = sum(1 for keyword in keywords if keyword in text_lower)
64
  scores[lang] = score
65
 
66
- detected_lang = max(scores, key=scores.get) if scores else 'unknown'
 
67
  return detected_lang.capitalize()
68
-
69
  def analyze_sentiment(self, text):
70
  """Advanced sentiment analysis with detailed metrics"""
 
 
 
 
 
 
 
 
 
 
 
 
71
  try:
72
- # Get predictions
73
  predictions = self.classifier(text)[0]
74
 
75
- # Convert to structured format
76
- sentiment_scores = {
77
- self.sentiment_map[i]: pred['score']
78
- for i, pred in enumerate(predictions)
79
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  # Determine dominant sentiment
82
  dominant_sentiment = max(sentiment_scores, key=sentiment_scores.get)
@@ -109,6 +161,7 @@ class AdvancedSentimentAnalyzer:
109
  }
110
 
111
  except Exception as e:
 
112
  return {
113
  'text': text,
114
  'sentiment': 'Neutral',
@@ -119,68 +172,83 @@ class AdvancedSentimentAnalyzer:
119
  'emotional_intensity': 0.0,
120
  'error': str(e)
121
  }
122
-
123
  def batch_analyze(self, texts):
124
  """Analyze multiple texts"""
125
- return [self.analyze_sentiment(text) for text in texts]
 
 
 
 
 
126
 
127
  # Initialize analyzer
 
128
  analyzer = AdvancedSentimentAnalyzer()
129
 
130
  def create_sentiment_chart(scores):
131
  """Create beautiful sentiment distribution chart"""
132
- fig = go.Figure(data=[
133
- go.Bar(
134
- x=list(scores.keys()),
135
- y=list(scores.values()),
136
- marker_color=[analyzer.sentiment_colors[sent] for sent in scores.keys()],
137
- text=[f'{score:.1%}' for score in scores.values()],
138
- textposition='auto',
 
 
 
 
 
 
 
 
 
 
139
  )
140
- ])
141
-
142
- fig.update_layout(
143
- title="Sentiment Distribution",
144
- xaxis_title="Sentiment",
145
- yaxis_title="Confidence Score",
146
- template="plotly_white",
147
- height=300
148
- )
149
-
150
- return fig
151
 
152
  def create_radar_chart(scores):
153
  """Create radar chart for sentiment analysis"""
154
- fig = go.Figure(data=go.Scatterpolar(
155
- r=list(scores.values()),
156
- theta=list(scores.keys()),
157
- fill='toself',
158
- line=dict(color='#4ECDC4'),
159
- marker=dict(size=8)
160
- ))
161
-
162
- fig.update_layout(
163
- polar=dict(
164
- radialaxis=dict(
165
- visible=True,
166
- range=[0, 1]
167
- )),
168
- showlegend=False,
169
- template="plotly_white",
170
- height=300
171
- )
172
-
173
- return fig
 
 
 
 
174
 
175
  def analyze_single_review(review_text):
176
  """Analyze single review with enhanced visualization"""
177
- if not review_text.strip():
178
- return "Please enter some text to analyze.", None, None
179
 
 
180
  result = analyzer.analyze_sentiment(review_text)
181
 
182
  # Create main output
183
- sentiment_color = analyzer.sentiment_colors[result['sentiment']]
184
 
185
  output_html = f"""
186
  <div style="padding: 25px; border-radius: 15px; background: linear-gradient(135deg, {sentiment_color}20, {sentiment_color}40); border-left: 5px solid {sentiment_color};">
@@ -226,12 +294,19 @@ def analyze_single_review(review_text):
226
  def analyze_csv_file(csv_file):
227
  """Analyze reviews from CSV file with advanced analytics"""
228
  try:
 
 
 
 
229
  df = pd.read_csv(csv_file.name)
230
 
231
  # Assume first column contains reviews
232
  review_column = df.columns[0]
233
  reviews = df[review_column].dropna().tolist()
234
 
 
 
 
235
  print(f"Analyzing {len(reviews)} reviews...")
236
  results = analyzer.batch_analyze(reviews)
237
 
@@ -270,13 +345,14 @@ def analyze_csv_file(csv_file):
270
  go.Pie(
271
  labels=sentiment_counts.index,
272
  values=sentiment_counts.values,
273
- marker_colors=[analyzer.sentiment_colors[sent] for sent in sentiment_counts.index]
274
  ), 1, 1
275
  )
276
 
277
- # Language pie chart
 
278
  fig.add_trace(
279
- go.Pie(labels=language_distribution.index, values=language_distribution.values),
280
  1, 2
281
  )
282
 
@@ -294,28 +370,28 @@ def analyze_csv_file(csv_file):
294
 
295
  # Generate comprehensive summary
296
  summary = f"""
297
- ๐Ÿ“Š **BATCH ANALYSIS COMPLETE**
298
 
299
  **Dataset Overview:**
300
- - ๐Ÿ“ Total Reviews Analyzed: {len(results):,}
301
- - ๐ŸŒ Languages Detected: {len(language_distribution)}
302
- - โฑ๏ธ Analysis Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
303
 
304
  **Sentiment Breakdown:**
305
- ๐ŸŸข Very Positive: {sentiment_counts.get('Very Positive', 0):,}
306
- ๐ŸŸก Positive: {sentiment_counts.get('Positive', 0):,}
307
- โšช Neutral: {sentiment_counts.get('Neutral', 0):,}
308
- ๐ŸŸ  Negative: {sentiment_counts.get('Negative', 0):,}
309
- ๐Ÿ”ด Very Negative: {sentiment_counts.get('Very Negative', 0):,}
310
 
311
  **Performance Metrics:**
312
- - ๐Ÿ“ˆ Average Confidence: {avg_confidence:.1%}
313
- - ๐ŸŽฏ Average Sentiment Score: {avg_sentiment_score:.2f}
314
- - ๐Ÿ† Most Common Language: {language_distribution.index[0] if len(language_distribution) > 0 else 'N/A'}
315
 
316
  **Files Generated:**
317
- - ๐Ÿ’พ Results CSV: `{output_filename}`
318
- - ๐Ÿ“Š Analytics Dashboard: See chart below
319
 
320
  **Next Steps:**
321
  - Download the CSV for detailed analysis
@@ -326,19 +402,22 @@ def analyze_csv_file(csv_file):
326
  return summary, output_filename, fig
327
 
328
  except Exception as e:
329
- return f"โŒ Error processing file: {str(e)}", None, None
 
 
330
 
331
- # Create enhanced Gradio interface
332
  with gr.Blocks(
333
- theme=gr.themes.Soft(),
334
  title="๐ŸŒ Multilingual Sentiment Analyzer",
335
  css="""
336
  .gradio-container {
337
  max-width: 1200px !important;
 
 
 
 
 
338
  }
339
- .sentiment-positive { border-left: 4px solid #6BCF7F !important; }
340
- .sentiment-negative { border-left: 4px solid #FF6B6B !important; }
341
- .sentiment-neutral { border-left: 4px solid #FFD93D !important; }
342
  """
343
  ) as demo:
344
 
@@ -357,8 +436,7 @@ with gr.Blocks(
357
  single_review = gr.Textbox(
358
  label="Enter text in any supported language",
359
  placeholder="Type your review here... (Supports 23 languages including English, Spanish, Chinese, French, German, Arabic, etc.)",
360
- lines=4,
361
- elem_id="review-input"
362
  )
363
  analyze_btn = gr.Button("๐Ÿš€ Analyze Sentiment", variant="primary")
364
 
@@ -389,8 +467,7 @@ with gr.Blocks(
389
  gr.Markdown("### ๐Ÿ“ค Upload CSV File")
390
  csv_upload = gr.File(
391
  label="Upload CSV file with reviews",
392
- file_types=[".csv"],
393
- type="filepath"
394
  )
395
  gr.Markdown("""
396
  **CSV Format Requirements:**
@@ -434,22 +511,13 @@ with gr.Blocks(
434
  - **Customer Support**: Analyze support tickets and feedback
435
  - **Social Media**: Monitor brand sentiment across languages
436
  - **Market Research**: Understand international customer opinions
437
-
438
- ### ๐Ÿ“Š Model Information
439
-
440
- - **Base Model**: `distilbert-base-multilingual-cased`
441
- - **Fine-tuned on**: Synthetic multilingual data
442
- - **Languages**: 23 languages including major world languages
443
- - **Accuracy**: State-of-the-art performance across languages
444
-
445
- ### ๐Ÿ”ง Technical Details
446
-
447
- The model uses a transformer architecture fine-tuned specifically for sentiment analysis across multiple languages and cultural contexts.
448
  """)
449
 
 
450
  if __name__ == "__main__":
451
  demo.launch(
452
- share=True,
453
  server_name="0.0.0.0",
 
454
  show_error=True
455
  )
 
8
  import plotly.express as px
9
  import plotly.graph_objects as go
10
  from plotly.subplots import make_subplots
11
+ import json
12
 
13
  class AdvancedSentimentAnalyzer:
14
  def __init__(self, model_name="tabularisai/multilingual-sentiment-analysis"):
15
+ print("Loading model and tokenizer...")
16
  self.model_name = model_name
17
+ try:
18
+ self.tokenizer = AutoTokenizer.from_pretrained(model_name)
19
+ self.model = AutoModelForSequenceClassification.from_pretrained(model_name)
20
+
21
+ # Use the modern pipeline syntax
22
+ self.classifier = pipeline(
23
+ "text-classification",
24
+ model=self.model,
25
+ tokenizer=self.tokenizer,
26
+ top_k=None # This replaces return_all_scores=True
27
+ )
28
+
29
+ except Exception as e:
30
+ print(f"Error loading model: {e}")
31
+ # Fallback to basic sentiment analysis
32
+ self.classifier = None
33
 
34
  self.sentiment_map = {
35
  0: "Very Negative",
 
48
  }
49
 
50
  self.language_detection_keywords = {
51
+ 'english': ['the', 'and', 'is', 'in', 'to', 'of', 'a', 'for'],
52
+ 'spanish': ['el', 'la', 'de', 'que', 'y', 'en', 'un', 'por'],
53
+ 'french': ['le', 'la', 'de', 'et', 'que', 'en', 'un', 'pour'],
54
+ 'german': ['der', 'die', 'das', 'und', 'zu', 'in', 'den', 'mit'],
55
+ 'italian': ['il', 'la', 'di', 'e', 'che', 'in', 'un', 'per'],
56
+ 'portuguese': ['o', 'a', 'de', 'e', 'que', 'em', 'um', 'para'],
57
+ 'dutch': ['de', 'het', 'en', 'van', 'te', 'in', 'een', 'voor'],
58
+ 'russian': ['ะธ', 'ะฒ', 'ะฝะต', 'ะฝะฐ', 'ั', 'ั‡ั‚ะพ', 'ะพะฝ', 'ั'],
59
+ 'chinese': ['็š„', 'ๆ˜ฏ', 'ๅœจ', 'ไบ†', 'ๆœ‰', 'ๅ’Œ', 'ไธบ', 'ๆˆ‘'],
60
+ 'japanese': ['ใฎ', 'ใซ', 'ใฏ', 'ใ‚’', 'ใŸ', 'ใŒ', 'ใง', 'ใฆ'],
61
+ 'korean': ['์ด', '์—', '๋Š”', '์„', '๋‹ค', '๊ฐ€', '๋กœ', '๊ณ '],
62
+ 'arabic': ['ุงู„', 'ููŠ', 'ู…ู†', 'ุนู„ู‰', 'ุฃู†', 'ู…ุง', 'ู‡ูˆ', 'ุฅู„ู‰'],
63
+ 'hindi': ['เค•เฅ€', 'เคธเฅ‡', 'เคนเฅˆ', 'เค”เคฐ', 'เค•เฅ‡', 'เคฎเฅ‡เค‚', 'เคฏเคน', 'เค•เฅ‹'],
64
+ 'turkish': ['ve', 'bir', 'bu', 'ile', 'iรงin', 'ama', 'da', 'de']
65
  }
66
+
67
+ print("Model loaded successfully!")
68
+
69
  def detect_language(self, text):
70
  """Simple language detection based on common words"""
71
+ if not text or not isinstance(text, str):
72
+ return 'Unknown'
73
+
74
  text_lower = text.lower()
75
  scores = {}
76
 
 
78
  score = sum(1 for keyword in keywords if keyword in text_lower)
79
  scores[lang] = score
80
 
81
+ # Only return a language if we have reasonable confidence
82
+ detected_lang = max(scores, key=scores.get) if scores and max(scores.values()) > 0 else 'unknown'
83
  return detected_lang.capitalize()
84
+
85
  def analyze_sentiment(self, text):
86
  """Advanced sentiment analysis with detailed metrics"""
87
+ if not text or not text.strip():
88
+ return {
89
+ 'text': text,
90
+ 'sentiment': 'Neutral',
91
+ 'confidence': 0.0,
92
+ 'scores': {sent: 0.2 for sent in self.sentiment_map.values()},
93
+ 'sentiment_score': 0,
94
+ 'language': 'Unknown',
95
+ 'emotional_intensity': 0.0,
96
+ 'error': 'No text provided'
97
+ }
98
+
99
  try:
100
+ # Get predictions using modern pipeline syntax
101
  predictions = self.classifier(text)[0]
102
 
103
+ # Convert to structured format - ensure proper mapping
104
+ sentiment_scores = {}
105
+ for pred in predictions:
106
+ label = pred['label']
107
+ score = pred['score']
108
+
109
+ # Map label to our sentiment scale
110
+ if 'very negative' in label.lower() or label == 'LABEL_0':
111
+ sentiment_scores["Very Negative"] = score
112
+ elif 'negative' in label.lower() or label == 'LABEL_1':
113
+ sentiment_scores["Negative"] = score
114
+ elif 'neutral' in label.lower() or label == 'LABEL_2':
115
+ sentiment_scores["Neutral"] = score
116
+ elif 'positive' in label.lower() or label == 'LABEL_3':
117
+ sentiment_scores["Positive"] = score
118
+ elif 'very positive' in label.lower() or label == 'LABEL_4':
119
+ sentiment_scores["Very Positive"] = score
120
+ else:
121
+ # Fallback: assign by order
122
+ sentiment_keys = list(self.sentiment_map.values())
123
+ for i, key in enumerate(sentiment_keys):
124
+ if key not in sentiment_scores:
125
+ sentiment_scores[key] = score
126
+ break
127
+
128
+ # Ensure all sentiment categories are present
129
+ for sentiment in self.sentiment_map.values():
130
+ if sentiment not in sentiment_scores:
131
+ sentiment_scores[sentiment] = 0.0
132
 
133
  # Determine dominant sentiment
134
  dominant_sentiment = max(sentiment_scores, key=sentiment_scores.get)
 
161
  }
162
 
163
  except Exception as e:
164
+ print(f"Error in sentiment analysis: {e}")
165
  return {
166
  'text': text,
167
  'sentiment': 'Neutral',
 
172
  'emotional_intensity': 0.0,
173
  'error': str(e)
174
  }
175
+
176
  def batch_analyze(self, texts):
177
  """Analyze multiple texts"""
178
+ results = []
179
+ for i, text in enumerate(texts):
180
+ if i % 10 == 0:
181
+ print(f"Processing {i}/{len(texts)}...")
182
+ results.append(self.analyze_sentiment(text))
183
+ return results
184
 
185
  # Initialize analyzer
186
+ print("Initializing sentiment analyzer...")
187
  analyzer = AdvancedSentimentAnalyzer()
188
 
189
  def create_sentiment_chart(scores):
190
  """Create beautiful sentiment distribution chart"""
191
+ try:
192
+ fig = go.Figure(data=[
193
+ go.Bar(
194
+ x=list(scores.keys()),
195
+ y=list(scores.values()),
196
+ marker_color=[analyzer.sentiment_colors[sent] for sent in scores.keys()],
197
+ text=[f'{score:.1%}' for score in scores.values()],
198
+ textposition='auto',
199
+ )
200
+ ])
201
+
202
+ fig.update_layout(
203
+ title="Sentiment Distribution",
204
+ xaxis_title="Sentiment",
205
+ yaxis_title="Confidence Score",
206
+ template="plotly_white",
207
+ height=300
208
  )
209
+
210
+ return fig
211
+ except Exception as e:
212
+ print(f"Error creating chart: {e}")
213
+ return None
 
 
 
 
 
 
214
 
215
  def create_radar_chart(scores):
216
  """Create radar chart for sentiment analysis"""
217
+ try:
218
+ fig = go.Figure(data=go.Scatterpolar(
219
+ r=list(scores.values()),
220
+ theta=list(scores.keys()),
221
+ fill='toself',
222
+ line=dict(color='#4ECDC4'),
223
+ marker=dict(size=8)
224
+ ))
225
+
226
+ fig.update_layout(
227
+ polar=dict(
228
+ radialaxis=dict(
229
+ visible=True,
230
+ range=[0, 1]
231
+ )),
232
+ showlegend=False,
233
+ template="plotly_white",
234
+ height=300
235
+ )
236
+
237
+ return fig
238
+ except Exception as e:
239
+ print(f"Error creating radar chart: {e}")
240
+ return None
241
 
242
  def analyze_single_review(review_text):
243
  """Analyze single review with enhanced visualization"""
244
+ if not review_text or not review_text.strip():
245
+ return "โŒ Please enter some text to analyze.", None, None
246
 
247
+ print(f"Analyzing: {review_text[:100]}...")
248
  result = analyzer.analyze_sentiment(review_text)
249
 
250
  # Create main output
251
+ sentiment_color = analyzer.sentiment_colors.get(result['sentiment'], '#FFD93D')
252
 
253
  output_html = f"""
254
  <div style="padding: 25px; border-radius: 15px; background: linear-gradient(135deg, {sentiment_color}20, {sentiment_color}40); border-left: 5px solid {sentiment_color};">
 
294
  def analyze_csv_file(csv_file):
295
  """Analyze reviews from CSV file with advanced analytics"""
296
  try:
297
+ if csv_file is None:
298
+ return "โŒ Please upload a CSV file.", None, None
299
+
300
+ print("Reading CSV file...")
301
  df = pd.read_csv(csv_file.name)
302
 
303
  # Assume first column contains reviews
304
  review_column = df.columns[0]
305
  reviews = df[review_column].dropna().tolist()
306
 
307
+ if not reviews:
308
+ return "โŒ No reviews found in the CSV file.", None, None
309
+
310
  print(f"Analyzing {len(reviews)} reviews...")
311
  results = analyzer.batch_analyze(reviews)
312
 
 
345
  go.Pie(
346
  labels=sentiment_counts.index,
347
  values=sentiment_counts.values,
348
+ marker_colors=[analyzer.sentiment_colors.get(sent, '#FFD93D') for sent in sentiment_counts.index]
349
  ), 1, 1
350
  )
351
 
352
+ # Language pie chart (top 10 languages)
353
+ top_languages = language_distribution.head(10)
354
  fig.add_trace(
355
+ go.Pie(labels=top_languages.index, values=top_languages.values),
356
  1, 2
357
  )
358
 
 
370
 
371
  # Generate comprehensive summary
372
  summary = f"""
373
+ ## ๐Ÿ“Š BATCH ANALYSIS COMPLETE
374
 
375
  **Dataset Overview:**
376
+ - ๐Ÿ“ **Total Reviews Analyzed:** {len(results):,}
377
+ - ๐ŸŒ **Languages Detected:** {len(language_distribution)}
378
+ - โฑ๏ธ **Analysis Timestamp:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
379
 
380
  **Sentiment Breakdown:**
381
+ - ๐ŸŸข **Very Positive:** {sentiment_counts.get('Very Positive', 0):,}
382
+ - ๐ŸŸก **Positive:** {sentiment_counts.get('Positive', 0):,}
383
+ - โšช **Neutral:** {sentiment_counts.get('Neutral', 0):,}
384
+ - ๐ŸŸ  **Negative:** {sentiment_counts.get('Negative', 0):,}
385
+ - ๐Ÿ”ด **Very Negative:** {sentiment_counts.get('Very Negative', 0):,}
386
 
387
  **Performance Metrics:**
388
+ - ๐Ÿ“ˆ **Average Confidence:** {avg_confidence:.1%}
389
+ - ๐ŸŽฏ **Average Sentiment Score:** {avg_sentiment_score:.2f}
390
+ - ๐Ÿ† **Most Common Language:** {language_distribution.index[0] if len(language_distribution) > 0 else 'N/A'}
391
 
392
  **Files Generated:**
393
+ - ๐Ÿ’พ **Results CSV:** `{output_filename}`
394
+ - ๐Ÿ“Š **Analytics Dashboard:** See chart below
395
 
396
  **Next Steps:**
397
  - Download the CSV for detailed analysis
 
402
  return summary, output_filename, fig
403
 
404
  except Exception as e:
405
+ error_msg = f"โŒ Error processing file: {str(e)}"
406
+ print(error_msg)
407
+ return error_msg, None, None
408
 
409
+ # Create Gradio interface with compatibility for Gradio 3.x
410
  with gr.Blocks(
 
411
  title="๐ŸŒ Multilingual Sentiment Analyzer",
412
  css="""
413
  .gradio-container {
414
  max-width: 1200px !important;
415
+ margin: 0 auto;
416
+ }
417
+ .container {
418
+ max-width: 1200px;
419
+ margin: 0 auto;
420
  }
 
 
 
421
  """
422
  ) as demo:
423
 
 
436
  single_review = gr.Textbox(
437
  label="Enter text in any supported language",
438
  placeholder="Type your review here... (Supports 23 languages including English, Spanish, Chinese, French, German, Arabic, etc.)",
439
+ lines=4
 
440
  )
441
  analyze_btn = gr.Button("๐Ÿš€ Analyze Sentiment", variant="primary")
442
 
 
467
  gr.Markdown("### ๐Ÿ“ค Upload CSV File")
468
  csv_upload = gr.File(
469
  label="Upload CSV file with reviews",
470
+ file_types=[".csv"]
 
471
  )
472
  gr.Markdown("""
473
  **CSV Format Requirements:**
 
511
  - **Customer Support**: Analyze support tickets and feedback
512
  - **Social Media**: Monitor brand sentiment across languages
513
  - **Market Research**: Understand international customer opinions
 
 
 
 
 
 
 
 
 
 
 
514
  """)
515
 
516
+ # Launch the application
517
  if __name__ == "__main__":
518
  demo.launch(
519
+ share=False,
520
  server_name="0.0.0.0",
521
+ debug=True,
522
  show_error=True
523
  )