""" Este módulo construye y lanza la interfaz de usuario web utilizando Gradio. Sirve como el punto de entrada de la aplicación y conecta la interfaz con la lógica de negocio definida en `src/logic.py`. """ import gradio as gr from src.logic import full_workflow, EXAMPLE_PDF_PATH import os # --- FUNCIONES AUXILIARES PARA LA INTERFAZ --- def check_requirements(): """ Verifica si los requisitos de configuración (API key y archivo de ejemplo) están presentes. Returns: Una tupla de booleanos (api_key_present, example_file_present). """ api_key_present = os.environ.get("GEMINI_API_KEY") is not None example_file_present = os.path.exists(EXAMPLE_PDF_PATH) return api_key_present, example_file_present def get_info_markdown(): """ Genera un texto en formato Markdown para mostrar el estado de la configuración en la UI. Esto proporciona retroalimentación en tiempo real al usuario. Returns: Un string en formato Markdown con el estado de la configuración. """ api_key_ok, example_file_ok = check_requirements() key_status = "✅ API Key de Gemini encontrada." if api_key_ok else "❌ **Acción Requerida**: Falta la API Key de Gemini. Por favor, configúrala en los secretos del repositorio de Hugging Face con el nombre `GEMINI_API_KEY`." file_status = f"✅ Archivo de ejemplo (`{EXAMPLE_PDF_PATH}`) encontrado." if example_file_ok else f"❌ **Acción Requerida**: Falta el archivo de ejemplo. Por favor, sube el archivo `{EXAMPLE_PDF_PATH}` a la raíz de este repositorio." all_ok = api_key_ok and example_file_ok return f""" ### Estado de la Configuración {key_status} {file_status} **La aplicación {'está lista para usarse' if all_ok else 'NO funcionará hasta que se resuelvan los puntos anteriores'}.** """ # --- DEFINICIÓN DE LA INTERFAZ DE GRADIO --- def create_interface(): """ Crea y devuelve el objeto de la interfaz de Gradio. """ # Se utiliza gr.Blocks para tener un control total sobre el diseño de la interfaz. with gr.Blocks(theme=gr.themes.Soft()) as iface: gr.Markdown("# 🤖 Asistente de Contestación de Tutelas con IA") gr.Markdown("Sube un documento de tutela en formato PDF y la IA generará una propuesta de contestación basada en un documento de ejemplo.") with gr.Row(): # Columna izquierda para entradas y controles. with gr.Column(scale=1): # Componente para subir el archivo PDF de la tutela. pdf_input = gr.File( label="Sube la Tutela", file_types=[".pdf"], type="filepath" # Pasa la ruta del archivo a la función, no el contenido. ) # Botón principal para iniciar el proceso. submit_btn = gr.Button("Generar Contestación", variant="primary") # Caja de información que muestra el estado de la configuración. # Se actualiza cada 5 segundos para reflejar cambios (ej. si el usuario sube el archivo). gr.Markdown(get_info_markdown, every=5) # Columna derecha para mostrar los resultados. with gr.Column(scale=2): gr.Markdown("### Borrador de la Contestación") # Pestañas para organizar las diferentes secciones de la respuesta. with gr.Tabs(): with gr.TabItem("Hechos"): hechos_output = gr.Textbox(label="Hechos", lines=10, interactive=True) with gr.TabItem("Fundamentos de Derecho"): fundamentos_output = gr.Textbox(label="Fundamentos de Derecho", lines=10, interactive=True) with gr.TabItem("Peticiones"): peticiones_output = gr.Textbox(label="Peticiones", lines=10, interactive=True) # Componente para mostrar el enlace de descarga del archivo .docx generado. docx_output = gr.File( label="Descargar Documento (.docx)", interactive=False # El usuario no puede subir un archivo aquí. ) # --- MANEJO DE EVENTOS --- # Conecta el evento 'click' del botón con la función de lógica de negocio. submit_btn.click( fn=full_workflow, # La función a ejecutar. inputs=[pdf_input], # La lista de componentes de entrada. outputs=[hechos_output, fundamentos_output, peticiones_output, docx_output], # La lista de componentes de salida. api_name="generate_tutela_response" # Nombre para la API de la interfaz. ) return iface # --- EJECUCIÓN PRINCIPAL --- # Crea la interfaz. Usar una variable global `demo` es un patrón común en Hugging Face Spaces. demo = create_interface() # Este bloque se ejecuta solo cuando el script se corre directamente. if __name__ == "__main__": # Lanza la aplicación web. demo.launch()