AIdeaText commited on
Commit
d73c879
·
verified ·
1 Parent(s): f199511

Update modules/semantic/semantic_interface.py

Browse files
Files changed (1) hide show
  1. modules/semantic/semantic_interface.py +295 -295
modules/semantic/semantic_interface.py CHANGED
@@ -1,296 +1,296 @@
1
- #modules/semantic/semantic_interface.py
2
- import streamlit as st
3
- from streamlit_float import *
4
- from streamlit_antd_components import *
5
- from streamlit.components.v1 import html
6
- import spacy_streamlit
7
- import io
8
- from io import BytesIO
9
- import base64
10
- import matplotlib.pyplot as plt
11
- import pandas as pd
12
- import re
13
- import logging
14
-
15
- # Configuración del logger
16
- logger = logging.getLogger(__name__)
17
-
18
- # Importaciones locales
19
- from .semantic_process import (
20
- process_semantic_input,
21
- format_semantic_results
22
- )
23
-
24
- from ..utils.widget_utils import generate_unique_key
25
- from ..database.semantic_mongo_db import store_student_semantic_result
26
- from ..database.chat_mongo_db import store_chat_history, get_chat_history
27
-
28
- # from ..database.semantic_export import export_user_interactions
29
-
30
-
31
- ###############################
32
-
33
- # En semantic_interface.py
34
- def display_semantic_interface(lang_code, nlp_models, semantic_t):
35
- try:
36
- # 1. Inicializar el estado de la sesión
37
- if 'semantic_state' not in st.session_state:
38
- st.session_state.semantic_state = {
39
- 'analysis_count': 0,
40
- 'last_analysis': None,
41
- 'current_file': None,
42
- 'pending_analysis': False # Nuevo flag para controlar el análisis pendiente
43
- }
44
-
45
- # 2. Área de carga de archivo con mensaje informativo
46
- st.info(semantic_t.get('initial_instruction',
47
- 'Para comenzar un nuevo análisis semántico, cargue un archivo de texto (.txt)'))
48
-
49
- uploaded_file = st.file_uploader(
50
- semantic_t.get('semantic_file_uploader', 'Upload a text file for semantic analysis'),
51
- type=['txt'],
52
- key=f"semantic_file_uploader_{st.session_state.semantic_state['analysis_count']}"
53
- )
54
-
55
- # Verificar si hay un archivo cargado y un análisis pendiente
56
- if uploaded_file is not None and st.session_state.semantic_state.get('pending_analysis', False):
57
- try:
58
- with st.spinner(semantic_t.get('processing', 'Processing...')):
59
- # Realizar análisis
60
- text_content = uploaded_file.getvalue().decode('utf-8')
61
-
62
- analysis_result = process_semantic_input(
63
- text_content,
64
- lang_code,
65
- nlp_models,
66
- semantic_t
67
- )
68
-
69
- if analysis_result['success']:
70
- # Guardar resultado
71
- st.session_state.semantic_result = analysis_result
72
- st.session_state.semantic_state['analysis_count'] += 1
73
- st.session_state.semantic_state['current_file'] = uploaded_file.name
74
-
75
- # Guardar en base de datos
76
- storage_success = store_student_semantic_result(
77
- st.session_state.username,
78
- text_content,
79
- analysis_result['analysis']
80
- )
81
-
82
- if storage_success:
83
- st.success(
84
- semantic_t.get('analysis_complete',
85
- 'Análisis completado y guardado. Para realizar un nuevo análisis, cargue otro archivo.')
86
- )
87
- else:
88
- st.error(semantic_t.get('error_message', 'Error saving analysis'))
89
- else:
90
- st.error(analysis_result['message'])
91
-
92
- # Restablecer el flag de análisis pendiente
93
- st.session_state.semantic_state['pending_analysis'] = False
94
-
95
- except Exception as e:
96
- logger.error(f"Error en análisis semántico: {str(e)}")
97
- st.error(semantic_t.get('error_processing', f'Error processing text: {str(e)}'))
98
- # Restablecer el flag de análisis pendiente en caso de error
99
- st.session_state.semantic_state['pending_analysis'] = False
100
-
101
- # 3. Columnas para los botones y mensajes
102
- col1, col2 = st.columns([1,4])
103
-
104
- # 4. Botón de análisis
105
- with col1:
106
- analyze_button = st.button(
107
- semantic_t.get('semantic_analyze_button', 'Analyze'),
108
- key=f"semantic_analyze_button_{st.session_state.semantic_state['analysis_count']}",
109
- type="primary",
110
- icon="🔍",
111
- disabled=uploaded_file is None,
112
- use_container_width=True
113
- )
114
-
115
- # 5. Procesar análisis
116
- if analyze_button and uploaded_file is not None:
117
- # En lugar de realizar el análisis inmediatamente, establecer el flag
118
- st.session_state.semantic_state['pending_analysis'] = True
119
- # Forzar la recarga de la aplicación
120
- st.rerun()
121
-
122
- # 6. Mostrar resultados previos o mensaje inicial
123
- elif 'semantic_result' in st.session_state and st.session_state.semantic_result is not None:
124
- # Mostrar mensaje sobre el análisis actual
125
- st.info(
126
- semantic_t.get('current_analysis_message',
127
- f'Mostrando análisis del archivo: {st.session_state.semantic_state["current_file"]}. '
128
- 'Para realizar un nuevo análisis, cargue otro archivo.')
129
- )
130
-
131
- display_semantic_results(
132
- st.session_state.semantic_result,
133
- lang_code,
134
- semantic_t
135
- )
136
- else:
137
- st.info(semantic_t.get('upload_prompt', 'Cargue un archivo para comenzar el análisis'))
138
-
139
- except Exception as e:
140
- logger.error(f"Error general en interfaz semántica: {str(e)}")
141
- st.error(semantic_t.get('general_error', "Se produjo un error. Por favor, intente de nuevo."))
142
-
143
-
144
- #######################################
145
- def display_semantic_results(semantic_result, lang_code, semantic_t):
146
- """
147
- Muestra los resultados del análisis semántico de conceptos clave.
148
- """
149
- if semantic_result is None or not semantic_result['success']:
150
- st.warning(semantic_t.get('no_results', 'No results available'))
151
- return
152
-
153
- analysis = semantic_result['analysis']
154
-
155
- # Mostrar conceptos clave en formato horizontal
156
- st.subheader(semantic_t.get('key_concepts', 'Key Concepts'))
157
- if 'key_concepts' in analysis and analysis['key_concepts']:
158
- # Crear tabla de conceptos
159
- df = pd.DataFrame(
160
- analysis['key_concepts'],
161
- columns=[
162
- semantic_t.get('concept', 'Concept'),
163
- semantic_t.get('frequency', 'Frequency')
164
- ]
165
- )
166
-
167
- # Convertir DataFrame a formato horizontal
168
- st.write(
169
- """
170
- <style>
171
- .concept-table {
172
- display: flex;
173
- flex-wrap: wrap;
174
- gap: 10px;
175
- margin-bottom: 20px;
176
- }
177
- .concept-item {
178
- background-color: #f0f2f6;
179
- border-radius: 5px;
180
- padding: 8px 12px;
181
- display: flex;
182
- align-items: center;
183
- gap: 8px;
184
- }
185
- .concept-name {
186
- font-weight: bold;
187
- }
188
- .concept-freq {
189
- color: #666;
190
- font-size: 0.9em;
191
- }
192
- </style>
193
- <div class="concept-table">
194
- """ +
195
- ''.join([
196
- f'<div class="concept-item"><span class="concept-name">{concept}</span>'
197
- f'<span class="concept-freq">({freq:.2f})</span></div>'
198
- for concept, freq in df.values
199
- ]) +
200
- "</div>",
201
- unsafe_allow_html=True
202
- )
203
- else:
204
- st.info(semantic_t.get('no_concepts', 'No key concepts found'))
205
-
206
- # Gráfico de conceptos
207
- st.subheader(semantic_t.get('concept_graph', 'Concepts Graph'))
208
- if 'concept_graph' in analysis and analysis['concept_graph'] is not None:
209
- try:
210
- # Container para el grafo con estilos mejorados
211
- st.markdown(
212
- """
213
- <style>
214
- .graph-container {
215
- background-color: white;
216
- border-radius: 10px;
217
- padding: 20px;
218
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
219
- margin: 10px 0;
220
- }
221
- .button-container {
222
- display: flex;
223
- gap: 10px;
224
- margin: 10px 0;
225
- }
226
- </style>
227
- """,
228
- unsafe_allow_html=True
229
- )
230
-
231
- with st.container():
232
- st.markdown('<div class="graph-container">', unsafe_allow_html=True)
233
-
234
- # Mostrar grafo
235
- graph_bytes = analysis['concept_graph']
236
- graph_base64 = base64.b64encode(graph_bytes).decode()
237
- st.markdown(
238
- f'<img src="data:image/png;base64,{graph_base64}" alt="Concept Graph" style="width:100%;"/>',
239
- unsafe_allow_html=True
240
- )
241
-
242
- # Leyenda del grafo
243
- st.caption(semantic_t.get(
244
- 'graph_description',
245
- 'Visualización de relaciones entre conceptos clave identificados en el texto.'
246
- ))
247
-
248
- st.markdown('</div>', unsafe_allow_html=True)
249
-
250
- # Contenedor para botones
251
- col1, col2 = st.columns([1,4])
252
- with col1:
253
- st.download_button(
254
- label="📥 " + semantic_t.get('download_graph', "Download"),
255
- data=graph_bytes,
256
- file_name="semantic_graph.png",
257
- mime="image/png",
258
- use_container_width=True
259
- )
260
-
261
- # Expandible con la interpretación
262
- with st.expander("📊 " + semantic_t.get('graph_help', "Graph Interpretation")):
263
- st.markdown("""
264
- - 🔀 Las flechas indican la dirección de la relación entre conceptos
265
- - 🎨 Los colores más intensos indican conceptos más centrales en el texto
266
- - ⭕ El tamaño de los nodos representa la frecuencia del concepto
267
- - ↔️ El grosor de las líneas indica la fuerza de la conexión
268
- """)
269
-
270
- except Exception as e:
271
- logger.error(f"Error displaying graph: {str(e)}")
272
- st.error(semantic_t.get('graph_error', 'Error displaying the graph'))
273
- else:
274
- st.info(semantic_t.get('no_graph', 'No concept graph available'))
275
-
276
-
277
- ########################################################################################
278
- '''
279
- # Botón de exportación al final
280
- if 'semantic_analysis_counter' in st.session_state:
281
- col1, col2, col3 = st.columns([2,1,2])
282
- with col2:
283
- if st.button(
284
- semantic_t.get('export_button', 'Export Analysis'),
285
- key=f"semantic_export_{st.session_state.semantic_analysis_counter}",
286
- use_container_width=True
287
- ):
288
- pdf_buffer = export_user_interactions(st.session_state.username, 'semantic')
289
- st.download_button(
290
- label=semantic_t.get('download_pdf', 'Download PDF'),
291
- data=pdf_buffer,
292
- file_name="semantic_analysis.pdf",
293
- mime="application/pdf",
294
- key=f"semantic_download_{st.session_state.semantic_analysis_counter}"
295
- )
296
  '''
 
1
+ #modules/semantic/semantic_interface.py
2
+ import streamlit as st
3
+ from streamlit_float import *
4
+ from streamlit_antd_components import *
5
+ from streamlit.components.v1 import html
6
+ import spacy_streamlit
7
+ import io
8
+ from io import BytesIO
9
+ import base64
10
+ import matplotlib.pyplot as plt
11
+ import pandas as pd
12
+ import re
13
+ import logging
14
+
15
+ # Configuración del logger
16
+ logger = logging.getLogger(__name__)
17
+
18
+ # Importaciones locales
19
+ from .semantic_process import (
20
+ process_semantic_input,
21
+ format_semantic_results
22
+ )
23
+
24
+ from ..utils.widget_utils import generate_unique_key
25
+ from ..database.semantic_mongo_db import store_student_semantic_result
26
+ from ..database.chat_mongo_db import store_chat_history, get_chat_history
27
+
28
+ # from ..database.semantic_export import export_user_interactions
29
+
30
+
31
+ ###############################
32
+
33
+ # En semantic_interface.py
34
+ def display_semantic_interface(lang_code, nlp_models, semantic_t):
35
+ try:
36
+ # 1. Inicializar el estado de la sesión
37
+ if 'semantic_state' not in st.session_state:
38
+ st.session_state.semantic_state = {
39
+ 'analysis_count': 0,
40
+ 'last_analysis': None,
41
+ 'current_file': None,
42
+ 'pending_analysis': False # Nuevo flag para controlar el análisis pendiente
43
+ }
44
+
45
+ # 2. Área de carga de archivo con mensaje informativo
46
+ st.info(semantic_t.get('initial_instruction',
47
+ 'Para comenzar un nuevo análisis semántico, cargue un archivo de texto (.txt)'))
48
+
49
+ uploaded_file = st.file_uploader(
50
+ semantic_t.get('semantic_file_uploader', 'Upload a text file for semantic analysis'),
51
+ type=['txt'],
52
+ key=f"semantic_file_uploader_{st.session_state.semantic_state['analysis_count']}"
53
+ )
54
+
55
+ # Verificar si hay un archivo cargado y un análisis pendiente
56
+ if uploaded_file is not None and st.session_state.semantic_state.get('pending_analysis', False):
57
+ try:
58
+ with st.spinner(semantic_t.get('processing', 'Processing...')):
59
+ # Realizar análisis
60
+ text_content = uploaded_file.getvalue().decode('utf-8')
61
+
62
+ analysis_result = process_semantic_input(
63
+ text_content,
64
+ lang_code,
65
+ nlp_models,
66
+ semantic_t
67
+ )
68
+
69
+ if analysis_result['success']:
70
+ # Guardar resultado
71
+ st.session_state.semantic_result = analysis_result
72
+ st.session_state.semantic_state['analysis_count'] += 1
73
+ st.session_state.semantic_state['current_file'] = uploaded_file.name
74
+
75
+ # Guardar en base de datos
76
+ storage_success = store_student_semantic_result(
77
+ st.session_state.username,
78
+ text_content,
79
+ analysis_result['analysis']
80
+ )
81
+
82
+ if storage_success:
83
+ st.success(
84
+ semantic_t.get('analysis_complete',
85
+ 'Análisis completado y guardado. Para realizar un nuevo análisis, cargue otro archivo.')
86
+ )
87
+ else:
88
+ st.error(semantic_t.get('error_message', 'Error saving analysis'))
89
+ else:
90
+ st.error(analysis_result['message'])
91
+
92
+ # Restablecer el flag de análisis pendiente
93
+ st.session_state.semantic_state['pending_analysis'] = False
94
+
95
+ except Exception as e:
96
+ logger.error(f"Error en análisis semántico: {str(e)}")
97
+ st.error(semantic_t.get('error_processing', f'Error processing text: {str(e)}'))
98
+ # Restablecer el flag de análisis pendiente en caso de error
99
+ st.session_state.semantic_state['pending_analysis'] = False
100
+
101
+ # 3. Columnas para los botones y mensajes
102
+ col1, col2 = st.columns([1,4])
103
+
104
+ # 4. Botón de análisis
105
+ with col1:
106
+ analyze_button = st.button(
107
+ semantic_t.get('semantic_analyze_button', 'Analyze'),
108
+ key=f"semantic_analyze_button_{st.session_state.semantic_state['analysis_count']}",
109
+ type="primary",
110
+ icon="🔍",
111
+ disabled=uploaded_file is None,
112
+ use_container_width=True
113
+ )
114
+
115
+ # 5. Procesar análisis
116
+ if analyze_button and uploaded_file is not None:
117
+ # En lugar de realizar el análisis inmediatamente, establecer el flag
118
+ st.session_state.semantic_state['pending_analysis'] = True
119
+ # Forzar la recarga de la aplicación
120
+ st.rerun()
121
+
122
+ # 6. Mostrar resultados previos o mensaje inicial
123
+ elif 'semantic_result' in st.session_state and st.session_state.semantic_result is not None:
124
+ # Mostrar mensaje sobre el análisis actual
125
+ st.info(
126
+ semantic_t.get('current_analysis_message',
127
+ f'Mostrando análisis del archivo: {st.session_state.semantic_state["current_file"]}. '
128
+ 'Para realizar un nuevo análisis, cargue otro archivo.')
129
+ )
130
+
131
+ display_semantic_results(
132
+ st.session_state.semantic_result,
133
+ lang_code,
134
+ semantic_t
135
+ )
136
+ else:
137
+ st.info(semantic_t.get('upload_prompt', 'Cargue un archivo para comenzar el análisis'))
138
+
139
+ except Exception as e:
140
+ logger.error(f"Error general en interfaz semántica: {str(e)}")
141
+ st.error(semantic_t.get('general_error', "Se produjo un error. Por favor, intente de nuevo."))
142
+
143
+
144
+ #######################################
145
+ def display_semantic_results(semantic_result, lang_code, semantic_t):
146
+ """
147
+ Muestra los resultados del análisis semántico de conceptos clave.
148
+ """
149
+ if semantic_result is None or not semantic_result['success']:
150
+ st.warning(semantic_t.get('no_results', 'No results available'))
151
+ return
152
+
153
+ analysis = semantic_result['analysis']
154
+
155
+ # Mostrar conceptos clave en formato horizontal
156
+ st.subheader(semantic_t.get('key_concepts', 'Key Concepts'))
157
+ if 'key_concepts' in analysis and analysis['key_concepts']:
158
+ # Crear tabla de conceptos
159
+ df = pd.DataFrame(
160
+ analysis['key_concepts'],
161
+ columns=[
162
+ semantic_t.get('concept', 'Concept'),
163
+ semantic_t.get('frequency', 'Frequency')
164
+ ]
165
+ )
166
+
167
+ # Convertir DataFrame a formato horizontal
168
+ st.write(
169
+ """
170
+ <style>
171
+ .concept-table {
172
+ display: flex;
173
+ flex-wrap: wrap;
174
+ gap: 10px;
175
+ margin-bottom: 20px;
176
+ }
177
+ .concept-item {
178
+ background-color: #f0f2f6;
179
+ border-radius: 5px;
180
+ padding: 8px 12px;
181
+ display: flex;
182
+ align-items: center;
183
+ gap: 8px;
184
+ }
185
+ .concept-name {
186
+ font-weight: bold;
187
+ }
188
+ .concept-freq {
189
+ color: #666;
190
+ font-size: 0.9em;
191
+ }
192
+ </style>
193
+ <div class="concept-table">
194
+ """ +
195
+ ''.join([
196
+ f'<div class="concept-item"><span class="concept-name">{concept}</span>'
197
+ f'<span class="concept-freq">({freq:.2f})</span></div>'
198
+ for concept, freq in df.values
199
+ ]) +
200
+ "</div>",
201
+ unsafe_allow_html=True
202
+ )
203
+ else:
204
+ st.info(semantic_t.get('no_concepts', 'No key concepts found'))
205
+
206
+ # Gráfico de conceptos
207
+ # st.subheader(semantic_t.get('concept_graph', 'Concepts Graph'))
208
+ if 'concept_graph' in analysis and analysis['concept_graph'] is not None:
209
+ try:
210
+ # Container para el grafo con estilos mejorados
211
+ st.markdown(
212
+ """
213
+ <style>
214
+ .graph-container {
215
+ background-color: white;
216
+ border-radius: 10px;
217
+ padding: 20px;
218
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
219
+ margin: 10px 0;
220
+ }
221
+ .button-container {
222
+ display: flex;
223
+ gap: 10px;
224
+ margin: 10px 0;
225
+ }
226
+ </style>
227
+ """,
228
+ unsafe_allow_html=True
229
+ )
230
+
231
+ with st.container():
232
+ st.markdown('<div class="graph-container">', unsafe_allow_html=True)
233
+
234
+ # Mostrar grafo
235
+ graph_bytes = analysis['concept_graph']
236
+ graph_base64 = base64.b64encode(graph_bytes).decode()
237
+ st.markdown(
238
+ f'<img src="data:image/png;base64,{graph_base64}" alt="Concept Graph" style="width:100%;"/>',
239
+ unsafe_allow_html=True
240
+ )
241
+
242
+ # Leyenda del grafo
243
+ st.caption(semantic_t.get(
244
+ 'graph_description',
245
+ 'Visualización de relaciones entre conceptos clave identificados en el texto.'
246
+ ))
247
+
248
+ st.markdown('</div>', unsafe_allow_html=True)
249
+
250
+ # Contenedor para botones
251
+ col1, col2 = st.columns([1,4])
252
+ with col1:
253
+ st.download_button(
254
+ label="📥 " + semantic_t.get('download_graph', "Download"),
255
+ data=graph_bytes,
256
+ file_name="semantic_graph.png",
257
+ mime="image/png",
258
+ use_container_width=True
259
+ )
260
+
261
+ # Expandible con la interpretación
262
+ with st.expander("📊 " + semantic_t.get('graph_help', "Graph Interpretation")):
263
+ st.markdown("""
264
+ - 🔀 Las flechas indican la dirección de la relación entre conceptos
265
+ - 🎨 Los colores más intensos indican conceptos más centrales en el texto
266
+ - ⭕ El tamaño de los nodos representa la frecuencia del concepto
267
+ - ↔️ El grosor de las líneas indica la fuerza de la conexión
268
+ """)
269
+
270
+ except Exception as e:
271
+ logger.error(f"Error displaying graph: {str(e)}")
272
+ st.error(semantic_t.get('graph_error', 'Error displaying the graph'))
273
+ else:
274
+ st.info(semantic_t.get('no_graph', 'No concept graph available'))
275
+
276
+
277
+ ########################################################################################
278
+ '''
279
+ # Botón de exportación al final
280
+ if 'semantic_analysis_counter' in st.session_state:
281
+ col1, col2, col3 = st.columns([2,1,2])
282
+ with col2:
283
+ if st.button(
284
+ semantic_t.get('export_button', 'Export Analysis'),
285
+ key=f"semantic_export_{st.session_state.semantic_analysis_counter}",
286
+ use_container_width=True
287
+ ):
288
+ pdf_buffer = export_user_interactions(st.session_state.username, 'semantic')
289
+ st.download_button(
290
+ label=semantic_t.get('download_pdf', 'Download PDF'),
291
+ data=pdf_buffer,
292
+ file_name="semantic_analysis.pdf",
293
+ mime="application/pdf",
294
+ key=f"semantic_download_{st.session_state.semantic_analysis_counter}"
295
+ )
296
  '''