Light-Dav commited on
Commit
17c021b
·
verified ·
1 Parent(s): 5dc3c79

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -63
app.py CHANGED
@@ -20,77 +20,112 @@ except Exception as e:
20
  model_loaded_successfully = False
21
  print("Sentiment analysis model failed to load. Please check MODEL_ID and network connection.")
22
 
23
- # --- Custom CSS for a dark look inspired by the website ---
24
- # Este CSS define todo el aspecto visual sin depender de un tema de Gradio
25
  custom_css = """
26
  body {
27
- background-color: #121212; /* Dark background */
28
- color: #f8f8f2; /* Light text */
 
29
  }
30
  .gradio-container {
31
- box-shadow: 0 4px 8px rgba(255, 255, 255, 0.1);
32
  border-radius: 10px;
33
  overflow: hidden;
34
- background-color: #1e1e1e; /* Darker card background */
35
  padding: 20px;
36
  margin-bottom: 20px;
 
37
  }
38
  h1, h2, h3 {
39
- color: #80cbc4; /* Teal/Cyan accents */
40
  text-align: center;
41
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
42
  animation: fadeIn 1s ease-in-out;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
  .gr-button.primary {
45
- background-color: #80cbc4 !important;
46
- color: #1e1e1e !important;
47
  border-radius: 6px;
48
  transition: background-color 0.3s ease;
49
- padding: 10px 20px;
 
 
 
50
  }
51
  .gr-button.primary:hover {
52
- background-color: #26a69a !important;
 
53
  }
54
  .gradio-output {
55
- border: 1px solid #424242;
56
  border-radius: 8px;
57
  padding: 15px;
58
  margin-top: 15px;
59
- background-color: #212121;
60
- color: #f8f8f2;
61
  }
62
  .sentiment-display {
63
  text-align: center;
64
  padding: 10px;
65
  border-radius: 6px;
66
  margin-top: 10px;
67
- font-size: 1.1em;
68
  font-weight: bold;
 
69
  }
70
  .sentiment-positive {
71
- background-color: #388e3c; /* Darker green */
72
- color: #e8f5e9; /* Light green */
73
  }
74
  .sentiment-negative {
75
- background-color: #d32f2f; /* Darker red */
76
- color: #ffebee; /* Light red */
77
  }
78
  .sentiment-neutral {
79
- background-color: #1976d2; /* Darker blue */
80
- color: #e3f2fd; /* Light blue */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
  @keyframes fadeIn {
83
  from { opacity: 0; }
84
  to { opacity: 1; }
85
  }
86
- /* Estilos para las etiquetas de los componentes de entrada */
87
- gr-textbox > label {
88
- color: #80cbc4;
89
- }
90
- /* Asegúrate de que las etiquetas de salida también tengan color */
91
- .gradio-output .label {
92
- color: #80cbc4; /* Color de acento para las etiquetas de salida */
93
- }
94
  """
95
 
96
  # --- Helper Function for Sentiment Interpretation ---
@@ -99,6 +134,8 @@ def interpret_sentiment(label, score):
99
  description = ""
100
  color_class = ""
101
 
 
 
102
  if label.lower() == "positive" or label.lower() == "label_2":
103
  emoji = "😊"
104
  description = "This text expresses a **highly positive** sentiment." if score > 0.9 else "This text expresses a **positive** sentiment."
@@ -117,62 +154,50 @@ def interpret_sentiment(label, score):
117
  color_class = ""
118
 
119
  return f"<div class='sentiment-display {color_class}'>{emoji} {label.upper()} ({score:.2f})</div>" + \
120
- f"<p>{description}</p>"
121
 
122
  # --- Sentiment Analysis Function ---
123
  def analyze_sentiment(text):
124
  if not model_loaded_successfully:
125
- # Devuelve 3 valores: HTML, dict, dict (para JSON)
126
  return (
127
- "<div class='sentiment-display'>⚠️ Model Not Loaded ⚠️</div><p>Please contact the administrator. The sentiment analysis model failed to load.</p>",
128
- {}, # Diccionario vacío para Confidence Scores
129
- {"error": "Model loading failed."} # Diccionario de error para Raw Output JSON
130
  )
131
 
132
  if not text.strip():
133
- # Devuelve 3 valores: HTML, dict, dict (para JSON)
134
  return (
135
- "<div class='sentiment-display'>✍️ Please enter some text! ✍️</div><p>Start typing to analyze its sentiment.</p>",
136
- {}, # Diccionario vacío para Confidence Scores
137
- {"info": "No text entered."} # Diccionario de info para Raw Output JSON
138
  )
139
 
140
  try:
141
- # Asegúrate de que la salida del pipeline es una lista de listas, y toma la primera.
142
  results = sentiment_analyzer(text)[0]
143
 
144
- # Ordenar los resultados por puntuación de confianza de mayor a menor
145
  results_sorted = sorted(results, key=lambda x: x['score'], reverse=True)
146
 
147
- # Tomar el primer elemento (el de mayor confianza)
148
  top_sentiment = results_sorted[0]
149
  label = top_sentiment['label']
150
  score = top_sentiment['score']
151
 
152
- # Crear un diccionario de puntuaciones de confianza para la salida de la etiqueta
153
  confidence_scores_output = {item['label']: item['score'] for item in results}
154
 
155
- # Generar el HTML para mostrar el sentimiento general
156
  overall_sentiment_display = interpret_sentiment(label, score)
157
 
158
- # ¡CORRECCIÓN FINAL AQUÍ! Pasa 'results' directamente, no str(results)
159
- # Gradio se encargará de serializar este objeto Python a JSON
160
  return (overall_sentiment_display, confidence_scores_output, results)
161
 
162
  except Exception as e:
163
- # En caso de cualquier error durante el análisis, devuelve 3 valores de error
164
  return (
165
- f"<div class='sentiment-display'>❌ Error ❌</div><p>An error occurred during analysis: {e}</p>",
166
- {}, # Diccionario vacío para Confidence Scores
167
- {"error_message": str(e)} # Diccionario de error para Raw Output JSON
168
  )
169
 
170
  # --- Gradio Interface ---
171
- # Al establecer theme=None, Gradio no aplicará ningún tema predefinido.
172
- # Todo el estilo visual vendrá de nuestro `custom_css`.
173
  with gr.Blocks(css=custom_css, theme=None) as demo:
174
- gr.Markdown("<h1 style='color: #80cbc4; text-align: center;'>🌌 Sentiment Analyzer 🌌</h1>")
175
- gr.Markdown("<p style='color: #f8f8f2; text-align: center;'>Uncover the emotional tone of your English text instantly.</p>")
176
 
177
  with gr.Column(elem_classes="gradio-container"):
178
  text_input = gr.Textbox(
@@ -184,10 +209,9 @@ with gr.Blocks(css=custom_css, theme=None) as demo:
184
  )
185
  analyze_btn = gr.Button("Analyze Sentiment", variant="primary")
186
 
187
- gr.Markdown("<hr style='border-top: 1px solid #424242;'>")
188
- gr.Markdown("<h3 style='color: #80cbc4; text-align: center;'>Try some examples:</h3>")
189
 
190
- # IMPORTANTE: Desactivamos cache_examples para evitar el FileNotFoundError
191
  examples = gr.Examples(
192
  examples=[
193
  ["This product exceeded my expectations, truly amazing!"],
@@ -199,21 +223,19 @@ with gr.Blocks(css=custom_css, theme=None) as demo:
199
  ],
200
  inputs=text_input,
201
  fn=analyze_sentiment,
202
- # Asegúrate de que estos 3 outputs coinciden con los 3 valores que devuelve analyze_sentiment
203
  outputs=[gr.HTML(label="Overall Sentiment"), gr.Label(num_top_classes=3, label="Confidence Scores"), gr.JSON(label="Raw Model Output", visible=False)],
204
- cache_examples=False # ESTE ES EL CAMBIO CLAVE PARA ELIMINAR EL FileNotFoundError
205
  )
206
 
207
- gr.Markdown("<hr style='border-top: 1px solid #424242;'>")
208
- gr.Markdown("<h2 style='color: #80cbc4;'>📊 Analysis Results</h2>")
209
 
210
- # Estas variables de salida deben coincidir en tipo y orden con lo que devuelve analyze_sentiment
211
  overall_sentiment_output = gr.HTML(label="Overall Sentiment")
212
  confidence_scores_output = gr.Label(num_top_classes=3, label="Confidence Scores")
213
- raw_output = gr.JSON(label="Raw Model Output", visible=False)
 
214
 
215
  # --- Event Listeners ---
216
- # Los outputs aquí también deben coincidir con los 3 valores que devuelve analyze_sentiment
217
  analyze_btn.click(
218
  fn=analyze_sentiment,
219
  inputs=text_input,
 
20
  model_loaded_successfully = False
21
  print("Sentiment analysis model failed to load. Please check MODEL_ID and network connection.")
22
 
23
+ # --- Custom CSS with the NEW COLOR PALETTE ---
 
24
  custom_css = """
25
  body {
26
+ background-color: #1E2B38; /* Fondo General Oscuro */
27
+ color: #FFFFFF; /* Blanco para texto principal */
28
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
29
  }
30
  .gradio-container {
31
+ box-shadow: 0 4px 8px rgba(0, 122, 204, 0.2); /* Sombra con Azul Oscuro */
32
  border-radius: 10px;
33
  overflow: hidden;
34
+ background-color: #1E2B38; /* Fondo de la tarjeta, coincide con el body para un look unificado */
35
  padding: 20px;
36
  margin-bottom: 20px;
37
+ border: 1px solid #007ACC; /* Borde sutil con Azul Oscuro */
38
  }
39
  h1, h2, h3 {
40
+ color: #00BFFF; /* Azul Brillante para títulos */
41
  text-align: center;
42
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
43
  animation: fadeIn 1s ease-in-out;
44
+ margin-top: 5px; /* Reducir margen superior de títulos */
45
+ margin-bottom: 15px; /* Reducir margen inferior de títulos */
46
+ }
47
+ p {
48
+ color: #AAB7C4; /* Gris medio para texto secundario */
49
+ text-align: center;
50
+ margin-bottom: 20px; /* Margen debajo de los párrafos */
51
+ }
52
+ .gr-textbox label, .gradio-output .label {
53
+ color: #AAB7C4 !important; /* Gris medio para las etiquetas de los componentes */
54
+ font-weight: bold;
55
+ }
56
+ .gr-textbox textarea {
57
+ background-color: #007ACC20; /* Azul Oscuro muy transparente para el fondo del textarea */
58
+ border: 1px solid #007ACC; /* Borde con Azul Oscuro */
59
+ color: #FFFFFF; /* Texto blanco en el textarea */
60
+ border-radius: 6px;
61
+ padding: 10px;
62
  }
63
  .gr-button.primary {
64
+ background-color: #00BFFF !important; /* Azul Brillante para el botón primario */
65
+ color: #1E2B38 !important; /* Texto oscuro para el botón primario */
66
  border-radius: 6px;
67
  transition: background-color 0.3s ease;
68
+ padding: 12px 25px; /* Ajuste de padding para el botón */
69
+ font-size: 1.1em;
70
+ font-weight: bold;
71
+ margin-top: 15px; /* Margen superior para separar del textarea */
72
  }
73
  .gr-button.primary:hover {
74
+ background-color: #007ACC !important; /* Azul Oscuro al pasar el ratón */
75
+ color: #FFFFFF !important; /* Texto blanco al pasar el ratón */
76
  }
77
  .gradio-output {
78
+ border: 1px solid #4A5B6C; /* Borde sutil con Gris Claro */
79
  border-radius: 8px;
80
  padding: 15px;
81
  margin-top: 15px;
82
+ background-color: #007ACC15; /* Fondo más sutil para la salida */
83
+ color: #FFFFFF; /* Texto blanco en la salida */
84
  }
85
  .sentiment-display {
86
  text-align: center;
87
  padding: 10px;
88
  border-radius: 6px;
89
  margin-top: 10px;
90
+ font-size: 1.2em; /* Un poco más grande para el resultado principal */
91
  font-weight: bold;
92
+ color: #FFFFFF; /* Texto blanco para todos los sentimientos */
93
  }
94
  .sentiment-positive {
95
+ background-color: #28a745; /* Verde Bootstrap similar */
 
96
  }
97
  .sentiment-negative {
98
+ background-color: #dc3545; /* Rojo Bootstrap similar */
 
99
  }
100
  .sentiment-neutral {
101
+ background-color: #007BFF; /* Azul Bootstrap similar */
102
+ }
103
+ .gradio-example-highlighted {
104
+ background-color: #00BFFF20 !important; /* Un poco de azul brillante para ejemplos seleccionados */
105
+ border: 1px solid #00BFFF !important;
106
+ }
107
+ .gradio-example-button {
108
+ background-color: #4A5B6C !important; /* Gris Claro para los botones de ejemplo */
109
+ color: #FFFFFF !important;
110
+ border: 1px solid #4A5B6C;
111
+ border-radius: 5px;
112
+ padding: 8px 12px;
113
+ margin: 5px;
114
+ transition: background-color 0.3s ease;
115
+ }
116
+ .gradio-example-button:hover {
117
+ background-color: #007ACC !important; /* Azul Oscuro al pasar el ratón por los ejemplos */
118
+ border-color: #00BFFF !important;
119
+ }
120
+ hr {
121
+ border-top: 1px solid #4A5B6C; /* Línea divisoria con Gris Claro */
122
+ margin-top: 25px;
123
+ margin-bottom: 25px;
124
  }
125
  @keyframes fadeIn {
126
  from { opacity: 0; }
127
  to { opacity: 1; }
128
  }
 
 
 
 
 
 
 
 
129
  """
130
 
131
  # --- Helper Function for Sentiment Interpretation ---
 
134
  description = ""
135
  color_class = ""
136
 
137
+ # Asegúrate de que las etiquetas coincidan con las salidas reales de tu modelo
138
+ # 'LABEL_0' es negativo, 'LABEL_1' es neutral, 'LABEL_2' es positivo
139
  if label.lower() == "positive" or label.lower() == "label_2":
140
  emoji = "😊"
141
  description = "This text expresses a **highly positive** sentiment." if score > 0.9 else "This text expresses a **positive** sentiment."
 
154
  color_class = ""
155
 
156
  return f"<div class='sentiment-display {color_class}'>{emoji} {label.upper()} ({score:.2f})</div>" + \
157
+ f"<p style='color: #FFFFFF;'>{description}</p>" # Asegurar que la descripción también sea blanca
158
 
159
  # --- Sentiment Analysis Function ---
160
  def analyze_sentiment(text):
161
  if not model_loaded_successfully:
 
162
  return (
163
+ "<div class='sentiment-display'>⚠️ Model Not Loaded ⚠️</div><p style='color: #FFFFFF;'>Please contact the administrator. The sentiment analysis model failed to load.</p>",
164
+ {},
165
+ {"error": "Model loading failed."}
166
  )
167
 
168
  if not text.strip():
 
169
  return (
170
+ "<div class='sentiment-display'>✍️ Please enter some text! ✍️</div><p style='color: #FFFFFF;'>Start typing to analyze its sentiment.</p>",
171
+ {},
172
+ {"info": "No text entered."}
173
  )
174
 
175
  try:
 
176
  results = sentiment_analyzer(text)[0]
177
 
 
178
  results_sorted = sorted(results, key=lambda x: x['score'], reverse=True)
179
 
 
180
  top_sentiment = results_sorted[0]
181
  label = top_sentiment['label']
182
  score = top_sentiment['score']
183
 
 
184
  confidence_scores_output = {item['label']: item['score'] for item in results}
185
 
 
186
  overall_sentiment_display = interpret_sentiment(label, score)
187
 
 
 
188
  return (overall_sentiment_display, confidence_scores_output, results)
189
 
190
  except Exception as e:
 
191
  return (
192
+ f"<div class='sentiment-display'>❌ Error ❌</div><p style='color: #FFFFFF;'>An error occurred during analysis: {e}</p>",
193
+ {},
194
+ {"error_message": str(e)}
195
  )
196
 
197
  # --- Gradio Interface ---
 
 
198
  with gr.Blocks(css=custom_css, theme=None) as demo:
199
+ gr.Markdown("<h1 style='color: #00BFFF;'>🌌 Sentiment Analyzer 🌌</h1>")
200
+ gr.Markdown("<p style='color: #AAB7C4;'>Uncover the emotional tone of your English text instantly.</p>")
201
 
202
  with gr.Column(elem_classes="gradio-container"):
203
  text_input = gr.Textbox(
 
209
  )
210
  analyze_btn = gr.Button("Analyze Sentiment", variant="primary")
211
 
212
+ gr.Markdown("<hr>")
213
+ gr.Markdown("<h3 style='color: #00BFFF;'>Try some examples:</h3>")
214
 
 
215
  examples = gr.Examples(
216
  examples=[
217
  ["This product exceeded my expectations, truly amazing!"],
 
223
  ],
224
  inputs=text_input,
225
  fn=analyze_sentiment,
 
226
  outputs=[gr.HTML(label="Overall Sentiment"), gr.Label(num_top_classes=3, label="Confidence Scores"), gr.JSON(label="Raw Model Output", visible=False)],
227
+ cache_examples=False
228
  )
229
 
230
+ gr.Markdown("<hr>")
231
+ gr.Markdown("<h2 style='color: #00BFFF;'>📊 Analysis Results</h2>")
232
 
 
233
  overall_sentiment_output = gr.HTML(label="Overall Sentiment")
234
  confidence_scores_output = gr.Label(num_top_classes=3, label="Confidence Scores")
235
+ # Deja Raw Model Output como visible=False para ahorrar espacio en el iframe por defecto
236
+ raw_output = gr.JSON(label="Raw Model Output", visible=False)
237
 
238
  # --- Event Listeners ---
 
239
  analyze_btn.click(
240
  fn=analyze_sentiment,
241
  inputs=text_input,