JairoCesar commited on
Commit
01fb88d
·
verified ·
1 Parent(s): c52e98f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -112
app.py CHANGED
@@ -7,45 +7,31 @@ import re
7
  import logging
8
  import datetime
9
 
10
- # Configurar logging para monitorear las llamadas al API
11
  logging.basicConfig(
12
  level=logging.INFO,
13
  format='%(asctime)s - %(levelname)s - %(message)s',
14
- handlers=[
15
- logging.StreamHandler() # Log a stdout/stderr
16
- ]
17
  )
18
  logger = logging.getLogger("rorschach_app")
19
 
20
- # Configuración mínima de Streamlit
21
- st.set_page_config(
22
- page_title="Interpretación Rorschach",
23
- page_icon="🧠",
24
- )
25
- import os
26
- from huggingface_hub import InferenceClient
27
 
28
- hf_token = os.getenv("HF_TOKEN")
29
- client = InferenceClient(
30
- model="mistralai/Mixtral-8x7B-Instruct-v0.1",
31
- token=hf_token
32
- )
33
 
34
-
35
-
36
- # Inicializar cliente - con log de verificación
37
- client = None
38
  try:
39
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
40
- logger.info("✅ Conexión con modelo Mistral-7B establecida correctamente")
41
  except Exception as e:
42
- error_msg = f"❌ Error al inicializar cliente de Hugging Face: {str(e)}"
43
- logger.error(error_msg)
44
- st.error(error_msg)
45
 
46
- # Function to format the prompt for Rorschach interpretation
47
  def format_prompt(message):
48
- # Prompt optimizado para interpretación Rorschach
49
  system_prompt = """Eres un experto en interpretación del Test de Rorschach.
50
  Analiza las respuestas del paciente a las láminas y proporciona una interpretación
51
  psicológica detallada basada en el método de Exner.
@@ -57,24 +43,18 @@ def format_prompt(message):
57
  - Originalidad/popularidad
58
  - Funcionamiento cognitivo, afectivo e interpersonal
59
  """
60
-
61
  prompt = f"<s>[INST] {system_prompt} [/INST] Entendido. [INST] Interpretación Rorschach: {message} [/INST]"
62
-
63
- # Log del prompt para verificación
64
  logger.info(f"Prompt generado con {len(prompt)} caracteres")
65
-
66
  return prompt
67
 
68
- # Function to generate response - con logs detallados
69
  def generate(prompt):
70
  if not client:
71
- logger.error("❌ No hay cliente disponible para generar respuesta")
72
- return "Error de conexión con el modelo. Por favor, inténtelo de nuevo más tarde."
73
-
74
  try:
75
- logger.info(f"🔄 Iniciando llamada al API de Hugging Face - {datetime.datetime.now()}")
76
-
77
- # Parámetros fijos optimizados para interpretación psicológica
78
  generate_kwargs = dict(
79
  temperature=0.7,
80
  max_new_tokens=800,
@@ -83,35 +63,24 @@ def generate(prompt):
83
  do_sample=True,
84
  seed=42,
85
  )
86
-
87
  formatted_prompt = format_prompt(prompt)
88
-
89
- # Monitoreo de tiempo de respuesta
90
- start_time = datetime.datetime.now()
91
-
92
- # Stream de la respuesta
93
- stream = client.text_generation(formatted_prompt, **generate_kwargs, stream=True, details=True, return_full_text=False)
94
  output = ""
95
  token_count = 0
96
-
97
  for response in stream:
98
  output += response.token.text
99
  token_count += 1
100
-
101
- end_time = datetime.datetime.now()
102
- duration = (end_time - start_time).total_seconds()
103
-
104
- # Log detallado del resultado
105
- logger.info(f"✅ Respuesta generada: {token_count} tokens en {duration:.2f} segundos")
106
-
107
  return output
108
-
109
  except Exception as e:
110
- error_msg = f"❌ Error en la generación: {str(e)}"
111
- logger.error(error_msg)
112
- return f"Lo siento, ocurrió un error durante la interpretación. Detalles: {str(e)}"
113
 
114
- # Function to replace variables in a Word template - sin cambios
115
  def replace_variables_word(doc, variables):
116
  for paragraph in doc.paragraphs:
117
  for key, value in variables.items():
@@ -125,98 +94,71 @@ def replace_variables_word(doc, variables):
125
  if f'<{key}>' in paragraph.text:
126
  paragraph.text = re.sub(f'<{key}>', value, paragraph.text)
127
 
128
- # Function to generate a Word document with interpretation - sin cambios
129
  def generate_word_document(interpretation):
130
  try:
131
  template_path = os.path.join('PLANTILLAS', 'PLANTILLA_INTERPRETACION.docx')
132
-
133
- # Verificar si existe la plantilla
134
  if not os.path.exists(template_path):
135
  logger.warning(f"⚠️ No se encontró la plantilla en {template_path}")
136
  st.warning(f"No se encontró la plantilla en {template_path}")
137
  return None
138
-
139
  doc = Document(template_path)
140
-
141
- variables = {'INTERPRETACION': interpretation}
142
- replace_variables_word(doc, variables)
143
-
144
  with tempfile.NamedTemporaryFile(delete=False, suffix='.docx') as tmp:
145
  doc.save(tmp.name)
146
- logger.info(f"✅ Documento Word generado correctamente: {tmp.name}")
147
  return tmp.name
148
-
149
  except Exception as e:
150
- error_msg = f"❌ Error al generar el documento: {str(e)}"
151
- logger.error(error_msg)
152
- st.error(error_msg)
153
  return None
154
 
155
- # Streamlit interface - simplificada al máximo
156
  st.title("Interpretación del Test de Rorschach")
157
-
158
- # Log de inicio de sesión
159
  logger.info("🚀 Aplicación iniciada")
160
 
161
- # User input - simplificado
162
  entrada_usuario = st.text_area(
163
  "Ingrese respuestas del Test de Rorschach:",
164
  height=150,
165
  placeholder="Ejemplo: Lámina I: Veo un murciélago..."
166
  )
167
 
168
- # UI simplificada con un solo botón
169
  if st.button("Enviar", type="primary"):
170
  if not entrada_usuario:
171
  st.warning("Por favor ingrese texto para interpretar")
172
  else:
173
- logger.info(f"🔄 Procesando entrada de {len(entrada_usuario)} caracteres")
174
-
175
- # UI feedback
176
  with st.spinner("Generando interpretación..."):
177
- # Generate response
178
  bot_response = generate(entrada_usuario)
179
-
180
- # UI para mostrar la respuesta
181
  st.subheader("Interpretación")
182
  st.write(bot_response)
183
-
184
- # Generate Word document
185
  document_path = generate_word_document(bot_response)
186
-
187
  if document_path:
188
- # Proporcionar enlace de descarga
189
  with open(document_path, "rb") as file:
190
- file_data = file.read()
191
-
192
- st.download_button(
193
- label="Descargar Interpretación",
194
- data=file_data,
195
- file_name="Interpretacion_Rorschach.docx",
196
- mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
197
- )
198
- logger.info("📄 Botón de descarga mostrado al usuario")
199
  else:
200
- logger.error("❌ No se pudo generar el documento Word")
201
 
202
- # Mostrar logs en la interfaz (para depuración)
203
  if st.checkbox("Mostrar logs", value=False):
204
  class StreamlitLogHandler(logging.Handler):
205
  def emit(self, record):
206
- log_entry = self.format(record)
207
- st.code(log_entry)
208
-
209
- # Mostrar los últimos 10 logs del sistema
210
  st.subheader("Logs del sistema")
211
- log_output = st.empty()
212
-
213
- # Agregar handler temporal para mostrar logs
214
- stream_handler = StreamlitLogHandler()
215
- stream_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
216
- logger.addHandler(stream_handler)
217
-
218
- # Generar log de prueba
219
  logger.info("📊 Visualización de logs activada")
220
-
221
- # Eliminar handler temporal
222
- logger.removeHandler(stream_handler)
 
7
  import logging
8
  import datetime
9
 
10
+ # Configurar logging
11
  logging.basicConfig(
12
  level=logging.INFO,
13
  format='%(asctime)s - %(levelname)s - %(message)s',
14
+ handlers=[logging.StreamHandler()]
 
 
15
  )
16
  logger = logging.getLogger("rorschach_app")
17
 
18
+ # Configuración de Streamlit
19
+ st.set_page_config(page_title="Interpretación Rorschach", page_icon="🧠")
 
 
 
 
 
20
 
21
+ # === Configurar el cliente de Hugging Face ===
22
+ HF_TOKEN = os.getenv("HF_TOKEN") or "TU_TOKEN_AQUI" # <-- Asegúrate de poner tu token aquí o definirlo como variable de entorno
23
+ MODEL_ID = "mistralai/Mixtral-8x7B-Instruct-v0.1"
 
 
24
 
 
 
 
 
25
  try:
26
+ client = InferenceClient(model=MODEL_ID, token=HF_TOKEN)
27
+ logger.info(f"✅ Conexión con el modelo {MODEL_ID} establecida correctamente")
28
  except Exception as e:
29
+ logger.error(f"❌ Error al inicializar cliente de Hugging Face: {str(e)}")
30
+ client = None
31
+ st.error("Error al conectar con el modelo de Hugging Face")
32
 
33
+ # Función para construir el prompt
34
  def format_prompt(message):
 
35
  system_prompt = """Eres un experto en interpretación del Test de Rorschach.
36
  Analiza las respuestas del paciente a las láminas y proporciona una interpretación
37
  psicológica detallada basada en el método de Exner.
 
43
  - Originalidad/popularidad
44
  - Funcionamiento cognitivo, afectivo e interpersonal
45
  """
 
46
  prompt = f"<s>[INST] {system_prompt} [/INST] Entendido. [INST] Interpretación Rorschach: {message} [/INST]"
 
 
47
  logger.info(f"Prompt generado con {len(prompt)} caracteres")
 
48
  return prompt
49
 
50
+ # Función para generar la interpretación
51
  def generate(prompt):
52
  if not client:
53
+ logger.error("❌ Cliente no disponible")
54
+ return "Error de conexión con el modelo."
55
+
56
  try:
57
+ logger.info("🔄 Iniciando generación de texto")
 
 
58
  generate_kwargs = dict(
59
  temperature=0.7,
60
  max_new_tokens=800,
 
63
  do_sample=True,
64
  seed=42,
65
  )
66
+
67
  formatted_prompt = format_prompt(prompt)
68
+ stream = client.text_generation(formatted_prompt, **generate_kwargs, stream=True, return_full_text=False)
 
 
 
 
 
69
  output = ""
70
  token_count = 0
71
+
72
  for response in stream:
73
  output += response.token.text
74
  token_count += 1
75
+
76
+ logger.info(f"✅ Respuesta generada: {token_count} tokens")
 
 
 
 
 
77
  return output
78
+
79
  except Exception as e:
80
+ logger.error(f"❌ Error en la generación: {str(e)}")
81
+ return f"Ocurrió un error: {str(e)}"
 
82
 
83
+ # Reemplazar variables en Word
84
  def replace_variables_word(doc, variables):
85
  for paragraph in doc.paragraphs:
86
  for key, value in variables.items():
 
94
  if f'<{key}>' in paragraph.text:
95
  paragraph.text = re.sub(f'<{key}>', value, paragraph.text)
96
 
97
+ # Generar documento Word
98
  def generate_word_document(interpretation):
99
  try:
100
  template_path = os.path.join('PLANTILLAS', 'PLANTILLA_INTERPRETACION.docx')
 
 
101
  if not os.path.exists(template_path):
102
  logger.warning(f"⚠️ No se encontró la plantilla en {template_path}")
103
  st.warning(f"No se encontró la plantilla en {template_path}")
104
  return None
105
+
106
  doc = Document(template_path)
107
+ replace_variables_word(doc, {'INTERPRETACION': interpretation})
108
+
 
 
109
  with tempfile.NamedTemporaryFile(delete=False, suffix='.docx') as tmp:
110
  doc.save(tmp.name)
111
+ logger.info(f"✅ Documento Word generado: {tmp.name}")
112
  return tmp.name
113
+
114
  except Exception as e:
115
+ logger.error(f"❌ Error generando documento: {str(e)}")
116
+ st.error(f"Error generando documento: {str(e)}")
 
117
  return None
118
 
119
+ # === Interfaz Streamlit ===
120
  st.title("Interpretación del Test de Rorschach")
 
 
121
  logger.info("🚀 Aplicación iniciada")
122
 
 
123
  entrada_usuario = st.text_area(
124
  "Ingrese respuestas del Test de Rorschach:",
125
  height=150,
126
  placeholder="Ejemplo: Lámina I: Veo un murciélago..."
127
  )
128
 
 
129
  if st.button("Enviar", type="primary"):
130
  if not entrada_usuario:
131
  st.warning("Por favor ingrese texto para interpretar")
132
  else:
133
+ logger.info(f"Procesando entrada de {len(entrada_usuario)} caracteres")
 
 
134
  with st.spinner("Generando interpretación..."):
 
135
  bot_response = generate(entrada_usuario)
136
+
 
137
  st.subheader("Interpretación")
138
  st.write(bot_response)
139
+
 
140
  document_path = generate_word_document(bot_response)
 
141
  if document_path:
 
142
  with open(document_path, "rb") as file:
143
+ st.download_button(
144
+ label="Descargar Interpretación",
145
+ data=file.read(),
146
+ file_name="Interpretacion_Rorschach.docx",
147
+ mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
148
+ )
149
+ logger.info("📄 Botón de descarga mostrado")
 
 
150
  else:
151
+ logger.error("❌ No se pudo generar el documento")
152
 
153
+ # Mostrar logs
154
  if st.checkbox("Mostrar logs", value=False):
155
  class StreamlitLogHandler(logging.Handler):
156
  def emit(self, record):
157
+ st.code(self.format(record))
158
+
 
 
159
  st.subheader("Logs del sistema")
160
+ handler = StreamlitLogHandler()
161
+ handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
162
+ logger.addHandler(handler)
 
 
 
 
 
163
  logger.info("📊 Visualización de logs activada")
164
+ logger.removeHandler(handler)