JairoCesar commited on
Commit
bde368b
verified
1 Parent(s): 43692ff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +251 -64
app.py CHANGED
@@ -4,97 +4,284 @@ from docx import Document
4
  import tempfile
5
  import os
6
  import re
 
 
7
 
8
- # Initialize the client
9
- client = InferenceClient("mistralai/Mistral-7B-Instruct-v0.2")
 
 
 
 
10
 
11
- # Function to format the prompt for Rorschach interpretation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  def format_prompt(message, history):
13
- prompt = "<s>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  for user_prompt, bot_response in history:
15
- prompt += f"[INST] {user_prompt} [/INST]"
16
- prompt += f" {bot_response} "
17
- prompt += f"[INST] Interpretaci贸n Rorschach: {message} [/INST]"
 
 
18
  return prompt
19
 
20
- # Function to generate response
21
- def generate(prompt, history, temperature=0.9, max_new_tokens=512, top_p=0.95, repetition_penalty=1.0):
22
- temperature = max(float(temperature), 1e-2)
23
- top_p = float(top_p)
24
-
25
- generate_kwargs = dict(
26
- temperature=temperature,
27
- max_new_tokens=max_new_tokens,
28
- top_p=top_p,
29
- repetition_penalty=repetition_penalty,
30
- do_sample=True,
31
- seed=42,
32
- )
33
-
34
- formatted_prompt = format_prompt(prompt, history)
35
-
36
- stream = client.text_generation(formatted_prompt, **generate_kwargs, stream=True, details=True, return_full_text=False)
37
- output = ""
38
- for response in stream:
39
- output += response.token.text
40
- return output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- # Function to replace variables in a Word template
43
  def replace_variables_word(doc, variables):
44
  for paragraph in doc.paragraphs:
45
  for key, value in variables.items():
46
  if f'<{key}>' in paragraph.text:
47
- paragraph.text = re.sub(f'<{key}>', value, paragraph.text)
 
 
 
 
 
 
 
 
 
 
48
  for table in doc.tables:
49
  for row in table.rows:
50
  for cell in row.cells:
51
  for paragraph in cell.paragraphs:
52
  for key, value in variables.items():
53
  if f'<{key}>' in paragraph.text:
54
- paragraph.text = re.sub(f'<{key}>', value, paragraph.text)
55
 
56
  # Function to generate a Word document with interpretation
57
- def generate_word_document(interpretation):
58
- template_path = os.path.join('PLANTILLAS', 'PLANTILLA_INTERPRETACION.docx')
59
- doc = Document(template_path)
60
-
61
- variables = {'INTERPRETACION': interpretation}
62
- replace_variables_word(doc, variables)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
- with tempfile.NamedTemporaryFile(delete=False, suffix='.docx') as tmp:
65
- doc.save(tmp.name)
66
- return tmp.name
 
 
 
67
 
68
- # Streamlit interface
69
- st.title("Interpretaci贸n del Test de Rorschach")
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  # Chat history
72
  if 'history' not in st.session_state:
73
  st.session_state.history = []
74
 
75
- # User input
76
- entrada_usuario = st.text_input("Que ves en las im谩genes ..:", key="entrada_usuario")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
  # Generate response and create Word document
79
- if st.button("Enviar"):
80
- if entrada_usuario:
81
- bot_response = generate(entrada_usuario, st.session_state.history)
 
 
 
 
 
 
 
82
  st.session_state.history.append((entrada_usuario, bot_response))
83
-
84
- # Generate Word document
85
- document_path = generate_word_document(bot_response)
86
 
87
- # Provide download link
88
- with open(document_path, "rb") as file:
89
- st.download_button(
90
- label="Descargar Interpretaci贸n",
91
- data=file,
92
- file_name="Interpretacion_Rorschach.docx",
93
- mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
94
- )
95
-
96
- # Display conversation
97
- chat_text = ""
98
- for user_msg, bot_msg in st.session_state.history:
99
- chat_text += f"Tu: {user_msg}\nBuho: {bot_msg}\n\n"
100
- st.text_area("Respuestas del Buho", value=chat_text, height=300, disabled=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  import tempfile
5
  import os
6
  import re
7
+ import time
8
+ from datetime import datetime
9
 
10
+ # Configuraci贸n de Streamlit
11
+ st.set_page_config(
12
+ page_title="Interpretaci贸n Test de Rorschach",
13
+ page_icon="馃",
14
+ layout="wide"
15
+ )
16
 
17
+ # Inicializaci贸n del cliente - usando API Token de Hugging Face
18
+ # Si tienes token, descomenta estas l铆neas y a帽ade tu token
19
+ # import os
20
+ # os.environ["HUGGINGFACE_TOKEN"] = "tu_token_aqu铆" # Mejor usar st.secrets en producci贸n
21
+
22
+ # Inicializar cliente con manejo de errores
23
+ @st.cache_resource
24
+ def get_inference_client():
25
+ try:
26
+ return InferenceClient(
27
+ model="mistralai/Mistral-7B-Instruct-v0.2",
28
+ timeout=120 # Timeout m谩s largo para respuestas extensas
29
+ )
30
+ except Exception as e:
31
+ st.error(f"Error al inicializar el cliente de Hugging Face: {str(e)}")
32
+ return None
33
+
34
+ client = get_inference_client()
35
+
36
+ # Function to format the prompt for Rorschach interpretation with mejor contexto
37
  def format_prompt(message, history):
38
+ # Sistema de instrucciones m谩s detallado para mejorar la interpretaci贸n
39
+ system_prompt = """Eres un experto en interpretaci贸n del Test de Rorschach.
40
+ Tu tarea es analizar las respuestas del paciente a las l谩minas y proporcionar una interpretaci贸n
41
+ psicol贸gica detallada basada en el m茅todo de Exner y el enfoque psicodin谩mico.
42
+
43
+ Para cada interpretaci贸n debes considerar:
44
+ 1. Localizaci贸n de las respuestas (W, D, Dd)
45
+ 2. Determinantes (forma, color, movimiento, sombreado)
46
+ 3. Contenido (humano, animal, objeto, etc.)
47
+ 4. Originalidad/popularidad de las respuestas
48
+ 5. Indicadores de funcionamiento cognitivo, afectivo e interpersonal
49
+
50
+ Tu interpretaci贸n debe ser profesional pero accesible, evitando jerga t茅cnica excesiva.
51
+ """
52
+
53
+ prompt = "<s>[INST] " + system_prompt + " [/INST] Entendido, analizar茅 las respuestas del Test de Rorschach profesionalmente.\n\n"
54
+
55
+ # A帽adir el historial de conversaci贸n
56
  for user_prompt, bot_response in history:
57
+ prompt += f"[INST] Respuestas a l谩minas: {user_prompt} [/INST]\n{bot_response}\n\n"
58
+
59
+ # A帽adir la consulta actual
60
+ prompt += f"[INST] Respuestas a l谩minas: {message} [/INST]"
61
+
62
  return prompt
63
 
64
+ # Function to generate response with manejo de errores y feedback visual
65
+ def generate(prompt, history, temperature=0.7, max_new_tokens=800, top_p=0.95, repetition_penalty=1.1):
66
+ if not client:
67
+ return "Error de conexi贸n con el modelo. Por favor, int茅ntelo de nuevo m谩s tarde."
68
+
69
+ try:
70
+ temperature = max(float(temperature), 1e-2)
71
+ top_p = float(top_p)
72
+
73
+ # Par谩metros optimizados para interpretaci贸n psicol贸gica
74
+ generate_kwargs = dict(
75
+ temperature=temperature,
76
+ max_new_tokens=max_new_tokens,
77
+ top_p=top_p,
78
+ repetition_penalty=repetition_penalty,
79
+ do_sample=True,
80
+ seed=42,
81
+ )
82
+
83
+ formatted_prompt = format_prompt(prompt, history)
84
+
85
+ # Mostrar indicador de progreso
86
+ progress_text = "Generando interpretaci贸n psicol贸gica..."
87
+ my_bar = st.progress(0, text=progress_text)
88
+
89
+ # Stream de la respuesta con feedback visual
90
+ stream = client.text_generation(formatted_prompt, **generate_kwargs, stream=True, details=True, return_full_text=False)
91
+ output = ""
92
+
93
+ for i, response in enumerate(stream):
94
+ output += response.token.text
95
+ # Actualizar la barra de progreso simulando avance
96
+ progress_percent = min(i/100, 1.0)
97
+ my_bar.progress(progress_percent, text=progress_text)
98
+ # Peque帽a pausa para mejorar UX
99
+ time.sleep(0.01)
100
+
101
+ # Completar la barra de progreso
102
+ my_bar.progress(1.0, text="隆Interpretaci贸n completa!")
103
+ time.sleep(0.5)
104
+ my_bar.empty()
105
+
106
+ return output
107
+
108
+ except Exception as e:
109
+ st.error(f"Error en la generaci贸n: {str(e)}")
110
+ return f"Lo siento, ocurri贸 un error durante la interpretaci贸n. Detalles: {str(e)}"
111
 
112
+ # Function to replace variables in a Word template con manejo mejorado
113
  def replace_variables_word(doc, variables):
114
  for paragraph in doc.paragraphs:
115
  for key, value in variables.items():
116
  if f'<{key}>' in paragraph.text:
117
+ # Preservar el formato existente
118
+ paragraph_format = paragraph.paragraph_format
119
+ run_formats = [(run.text, run.bold, run.italic, run.font.size, run.font.name)
120
+ for run in paragraph.runs]
121
+
122
+ paragraph.text = paragraph.text.replace(f'<{key}>', value)
123
+
124
+ # Restablecer formato despu茅s del reemplazo si es necesario
125
+ paragraph.paragraph_format = paragraph_format
126
+
127
+ # Procesar tablas
128
  for table in doc.tables:
129
  for row in table.rows:
130
  for cell in row.cells:
131
  for paragraph in cell.paragraphs:
132
  for key, value in variables.items():
133
  if f'<{key}>' in paragraph.text:
134
+ paragraph.text = paragraph.text.replace(f'<{key}>', value)
135
 
136
  # Function to generate a Word document with interpretation
137
+ def generate_word_document(interpretation, patient_name="", test_date=""):
138
+ try:
139
+ template_path = os.path.join('PLANTILLAS', 'PLANTILLA_INTERPRETACION.docx')
140
+
141
+ # Verificar si existe la plantilla
142
+ if not os.path.exists(template_path):
143
+ st.warning(f"No se encontr贸 la plantilla en {template_path}. Usando documento en blanco.")
144
+ doc = Document()
145
+ doc.add_heading('Interpretaci贸n Test de Rorschach', 0)
146
+ doc.add_paragraph(interpretation)
147
+ else:
148
+ doc = Document(template_path)
149
+
150
+ # Preparar variables para la plantilla
151
+ variables = {
152
+ 'INTERPRETACION': interpretation,
153
+ 'NOMBRE_PACIENTE': patient_name,
154
+ 'FECHA_EVALUACION': test_date,
155
+ 'FECHA_INFORME': datetime.now().strftime("%d/%m/%Y")
156
+ }
157
+
158
+ replace_variables_word(doc, variables)
159
+
160
+ # Guardar el documento temporal
161
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.docx') as tmp:
162
+ doc.save(tmp.name)
163
+ return tmp.name
164
+
165
+ except Exception as e:
166
+ st.error(f"Error al generar el documento: {str(e)}")
167
+ return None
168
 
169
+ # Interfaz de Streamlit mejorada
170
+ st.title("馃 Interpretaci贸n del Test de Rorschach")
171
+ st.markdown("""
172
+ Esta aplicaci贸n utiliza inteligencia artificial para ayudar en la interpretaci贸n preliminar
173
+ de respuestas al Test de Rorschach. **No sustituye el juicio cl铆nico profesional.**
174
+ """)
175
 
176
+ # Sidebar con opciones
177
+ with st.sidebar:
178
+ st.header("Configuraci贸n")
179
+
180
+ # Par谩metros del paciente
181
+ st.subheader("Datos del Paciente")
182
+ patient_name = st.text_input("Nombre del paciente (opcional)")
183
+ test_date = st.date_input("Fecha de evaluaci贸n", datetime.now()).strftime("%d/%m/%Y")
184
+
185
+ # Par谩metros del modelo
186
+ st.subheader("Par谩metros del Modelo")
187
+ temperature = st.slider("Temperatura", 0.1, 1.0, 0.7, 0.1,
188
+ help="Valores m谩s altos = respuestas m谩s creativas. Valores m谩s bajos = respuestas m谩s consistentes.")
189
+ max_tokens = st.slider("Longitud m谩xima", 200, 1500, 800, 100,
190
+ help="N煤mero m谩ximo de tokens en la respuesta")
191
 
192
  # Chat history
193
  if 'history' not in st.session_state:
194
  st.session_state.history = []
195
 
196
+ # Explicaci贸n del uso
197
+ with st.expander("鈩癸笍 C贸mo usar esta aplicaci贸n"):
198
+ st.markdown("""
199
+ 1. Escribe las respuestas del paciente a las l谩minas del Test de Rorschach en el campo de texto.
200
+ 2. Incluye el n煤mero de l谩mina para cada respuesta, por ejemplo: "L谩mina I: Veo un murci茅lago".
201
+ 3. Haz clic en "Generar Interpretaci贸n" para recibir el an谩lisis.
202
+ 4. Puedes descargar la interpretaci贸n como documento Word.
203
+
204
+ **Nota importante**: Esta herramienta est谩 dise帽ada para asistir en la interpretaci贸n preliminar.
205
+ Siempre debe complementarse con el juicio cl铆nico de un profesional cualificado.
206
+ """)
207
+
208
+ # Uso de columnas para mejor distribuci贸n
209
+ col1, col2 = st.columns([3, 2])
210
+
211
+ with col1:
212
+ # User input - 谩rea de texto m谩s grande para m煤ltiples respuestas
213
+ entrada_usuario = st.text_area(
214
+ "Ingrese las respuestas del paciente a las l谩minas:",
215
+ height=200,
216
+ placeholder="Ejemplo:\nL谩mina I: Veo un murci茅lago\nL谩mina II: Dos personas chocando las manos, hay sangre\n..."
217
+ )
218
+
219
+ # Botones de acci贸n
220
+ col_btn1, col_btn2, _ = st.columns([1, 1, 2])
221
+
222
+ with col_btn1:
223
+ submit_button = st.button("Generar Interpretaci贸n", type="primary")
224
+
225
+ with col_btn2:
226
+ clear_button = st.button("Limpiar Historial")
227
+ if clear_button:
228
+ st.session_state.history = []
229
+ st.experimental_rerun()
230
 
231
  # Generate response and create Word document
232
+ if submit_button and entrada_usuario:
233
+ with st.spinner("Analizando respuestas..."):
234
+ bot_response = generate(
235
+ entrada_usuario,
236
+ st.session_state.history,
237
+ temperature=temperature,
238
+ max_new_tokens=max_tokens
239
+ )
240
+
241
+ # A帽adir al historial
242
  st.session_state.history.append((entrada_usuario, bot_response))
 
 
 
243
 
244
+ # Generar documento Word
245
+ document_path = generate_word_document(
246
+ bot_response,
247
+ patient_name=patient_name,
248
+ test_date=test_date
249
+ )
250
+
251
+ if document_path:
252
+ # Proporcionar enlace de descarga
253
+ with open(document_path, "rb") as file:
254
+ file_data = file.read()
255
+
256
+ # Nombre personalizado para el archivo
257
+ file_name = f"Interpretacion_Rorschach_{datetime.now().strftime('%Y%m%d')}.docx"
258
+ if patient_name:
259
+ file_name = f"Rorschach_{patient_name.replace(' ', '_')}_{datetime.now().strftime('%Y%m%d')}.docx"
260
+
261
+ with col2:
262
+ st.download_button(
263
+ label="馃搫 Descargar Interpretaci贸n (Word)",
264
+ data=file_data,
265
+ file_name=file_name,
266
+ mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
267
+ )
268
+
269
+ # Display conversation en la segunda columna
270
+ with col2:
271
+ st.subheader("Historial de Interpretaciones")
272
+
273
+ if not st.session_state.history:
274
+ st.info("A煤n no hay interpretaciones generadas. Complete el formulario y haga clic en 'Generar Interpretaci贸n'.")
275
+ else:
276
+ # Mostrar la 煤ltima interpretaci贸n primero
277
+ for i, (user_msg, bot_msg) in enumerate(reversed(st.session_state.history)):
278
+ with st.expander(f"Interpretaci贸n {len(st.session_state.history) - i}", expanded=(i == 0)):
279
+ st.markdown("**Respuestas del paciente:**")
280
+ st.text(user_msg)
281
+ st.markdown("**Interpretaci贸n psicol贸gica:**")
282
+ st.markdown(bot_msg)
283
+
284
+ # Pie de p谩gina
285
+ st.markdown("---")
286
+ st.markdown("馃搶 **Nota**: Esta aplicaci贸n usa el modelo Mistral-7B para generar interpretaciones preliminares.")
287
+ st.markdown("鈿狅笍 Los resultados deben ser revisados por un profesional cualificado antes de usarse en contextos cl铆nicos.")