cfee/generador-post-mortem
1
1import os2 3import streamlit as st4from incident_crew import IncidentReporterCrew5 6 7# --- Interfaz de Usuario con Streamlit ---8st.set_page_config(9 page_title="Generador IA de Informes Post-Mortem",10 layout="wide"11)12 13# Inicializar el estado de la sesión para la API Key si no existe14if 'llm_api_key' not in st.session_state:15 st.session_state['llm_api_key'] = os.getenv("OPENAI_API_KEY", "")16 17if 'ipinfo_api_key' not in st.session_state:18 st.session_state['ipinfo_api_key'] = os.getenv("IPINFO_API_KEY", "")19 20# --- Sidebar para la configuración de la API Key ---21with st.sidebar:22 st.title("📄 Generador de Informes Post-Mortem asistido por IA")23 st.write("- 📄 Completa el formulario con los detalles de la incidencia")24 st.write("- 🚀 Presiona el botón y la IA generará un informe técnico estructurado post-mortem de tu incidente.")25 26 # Campo de entrada para la API Key27 if not os.getenv("OPENAI_API_KEY"):28 st.session_state['llm_api_key'] = st.text_input(29 "- 🔑 Ingresa tu API Key para el LLM",30 type="password",31 value=st.session_state['llm_api_key']32 )33 34 if st.session_state['llm_api_key']:35 st.success("Agent API Key cargada!")36 else:37 st.warning("🚨 Por favor, ingresa tu API Key para el LLM.")38 39 if not os.getenv("IPINFO_API_KEY"):40 st.session_state['ipinfo_api_key'] = st.text_input(41 "- 🔑 Ingresa tu API Key de IPInfo",42 type="password",43 value=st.session_state['ipinfo_api_key']44 )45 46 if st.session_state['ipinfo_api_key']:47 st.success("IPInfo API Key cargada!")48 else:49 st.warning("🚨 Por favor, ingresa tu API Key de IPInfo.")50 51 52# --- Formulario de entrada de datos principal ---53with st.form("post_mortem_form"):54 # Usar session_state para precompletar si corresponde55 col1, col2 = st.columns(2)56 with col1:57 tipo_alerta = st.text_input(58 "Tipo de Alerta / Título del Problema",59 placeholder="Ej: High CPU usage en DB Server; Caída del servicio de Login",60 )61 sistema_afectado = st.text_input(62 "Sistema Afectado",63 placeholder="Ej: Servidor de Base de Datos; Microservicio de Autenticación",64 )65 with col2:66 fecha_hora = st.text_input(67 "Fecha y Hora",68 placeholder="Ej: 26/Sep/2025 21:45 PM UTC-3",69 )70 71 impacto_detalle = st.text_area(72 "Detalles del incidente e Impacto",73 placeholder="Ej: Latencia elevada afectó al 20% de los usuarios.",74 height=150,75 )76 77 acciones_tomadas = st.text_area(78 "Acciones Tomadas (Mitigación Inmediata)",79 placeholder="Ej: Se escaló a Dev Team. Se reinició el servicio crítico.",80 height=150,81 )82 83 # Botón de envío84 submitted = st.form_submit_button("🚀 Generar Informe Post-Mortem")85 86# --- Lógica de procesamiento ---87if submitted:88 89 #if not st.session_state.get('gemini_api_key'):90 #st.error("❌ Por favor, ingresa tu API Key de Gemini en el panel lateral (sidebar) antes de continuar.")91 92 if not all([tipo_alerta, sistema_afectado, fecha_hora, impacto_detalle, acciones_tomadas]):93 st.error("❌ Por favor, completa todos los campos del formulario para generar el informe.")94 95 else:96 inputs = {97 "tipo_alerta": tipo_alerta,98 "sistema_afectado": sistema_afectado,99 "fecha_hora": fecha_hora,100 "impacto_detalle": impacto_detalle,101 "acciones_tomadas": acciones_tomadas,102 }103 104 with st.spinner("⏳ Generando informe técnico..."):105 crew_response = IncidentReporterCrew(106 api_key=st.session_state['llm_api_key'],107 ).crew().kickoff(inputs=inputs)108 109 lineas = crew_response.raw.splitlines()110 111 if len(lineas) >= 2:112 lineas.pop(0) # Elimina la primera línea113 lineas.pop() # Elimina la última línea114 final_report = "\n".join(lineas)115 116 # Mostrar el resultado117 st.divider()118 st.success("✅ Informe post-mortem generado correctamente.")119 #st.code(incident_crew.usage_metrics)120 st.markdown(final_report)121 st.download_button(122 label="Descargar Informe (.md)",123 data=final_report,124 file_name="post_mortem_incidencia.md",125 mime="text/markdown",126 on_click="ignore"127 )