v3 / modules /morphosyntax /morphosyntax_interface.py
AIdeaText's picture
Update modules/morphosyntax/morphosyntax_interface.py
344632c verified
raw
history blame
9.68 kB
# modules/morphosyntax/morphosyntax_interface.py
import streamlit as st
import re
import logging
from spacy import displacy
# Importa tu pipeline de spacy, por ejemplo:
# nlp_models = {"es": spacy.load("es_core_news_sm")}
# Supongamos que estas funciones existen en tus otros m贸dulos:
from ..morphosyntax.morphosyntax_process import perform_advanced_morphosyntactic_analysis
from ..database.morphosyntax_iterative_mongo_db import (
store_student_morphosyntax_base,
store_student_morphosyntax_iteration,
)
logger = logging.getLogger(__name__)
###########################################################################
def initialize_arc_analysis_state():
"""
Inicializa el estado de an谩lisis de arcos (base e iteraciones) si no existe.
"""
if "arc_analysis_state" not in st.session_state:
st.session_state.arc_analysis_state = {
"base_id": None, # ObjectId del documento base
"base_text": "", # Texto inicial
"base_diagram": None, # HTML del diagrama base
"iteration_text": "", # Texto de iteraci贸n
"iteration_diagram": None, # HTML del diagrama de iteraci贸n
}
logger.info("Estado de an谩lisis de arcos inicializado.")
###########################################################################
def reset_arc_analysis_state():
"""
Resetea completamente el estado de an谩lisis de arcos.
"""
st.session_state.arc_analysis_state = {
"base_id": None,
"base_text": "",
"base_diagram": None,
"iteration_text": "",
"iteration_diagram": None,
}
###########################################################################
def display_arc_diagram(doc):
"""
Genera y retorna el HTML del diagrama de arco para un `Doc` de spaCy.
No imprime directamente en pantalla; regresa el HTML para que se
renderice con `st.write(..., unsafe_allow_html=True)`.
"""
try:
diagram_html = ""
for sent in doc.sents:
svg_html = displacy.render(
sent,
style="dep",
options={
"distance": 100,
"arrow_spacing": 20,
"word_spacing": 30,
}
)
# Ajustar tama帽o y posici贸n
svg_html = svg_html.replace('height="375"', 'height="200"')
svg_html = re.sub(
r'<svg[^>]*>',
lambda m: m.group(0).replace('height="450"', 'height="300"'),
svg_html
)
svg_html = re.sub(
r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
lambda m: f'<g transform="translate({m.group(1)},50)"',
svg_html
)
# Envolver en contenedor con estilo
diagram_html += f'<div class="arc-diagram-container">{svg_html}</div>'
return diagram_html
except Exception as e:
logger.error(f"Error en display_arc_diagram: {str(e)}")
return "<p style='color:red;'>Error generando diagrama</p>"
###########################################################################
def display_morphosyntax_interface(lang_code, nlp_models):
"""
Interfaz principal para la visualizaci贸n de diagramas de arco
(Texto Base vs Iteraciones).
"""
# CSS para layout estable
st.markdown("""
<style>
.stTextArea textarea {
font-size: 1rem;
line-height: 1.5;
min-height: 100px !important;
height: 100px !important;
}
.arc-diagram-container {
width: 100%;
padding: 0.5rem;
margin: 0.5rem 0;
}
.divider {
height: 3px;
border: none;
background-color: #333;
margin: 2rem 0;
}
</style>
""", unsafe_allow_html=True)
# Inicializar el estado si no existe
initialize_arc_analysis_state()
arc_state = st.session_state.arc_analysis_state # Para abreviar
# Creamos pesta帽as: "Texto Base" y "Iteraciones"
tabs = st.tabs(["Texto Base", "Iteraciones"])
# ------------------- PESTA脩A 1: Texto Base --------------------------
with tabs[0]:
st.subheader("An谩lisis de Texto Base")
# Bot贸n para resetear todo
if st.button("Nuevo An谩lisis", key="btn_reset_base"):
reset_arc_analysis_state()
st.experimental_rerun()
# Input para texto base
arc_state["base_text"] = st.text_area(
"Ingrese su texto inicial",
value=arc_state["base_text"],
key="base_text_input",
height=120
)
# Bot贸n de an谩lisis base
if st.button("Analizar Texto Base", key="btn_analyze_base"):
if not arc_state["base_text"].strip():
st.warning("Ingrese un texto para analizar.")
else:
try:
# Procesar con spaCy
doc = nlp_models[lang_code](arc_state["base_text"])
# Generar HTML del arco
base_arc_html = display_arc_diagram(doc)
arc_state["base_diagram"] = base_arc_html
# Guardar en BD usando tu an谩lisis avanzado
analysis = perform_advanced_morphosyntactic_analysis(
arc_state["base_text"],
nlp_models[lang_code]
)
base_id = store_student_morphosyntax_base(
username=st.session_state.username,
text=arc_state["base_text"],
arc_diagrams=analysis["arc_diagrams"]
)
if base_id:
arc_state["base_id"] = base_id
st.success(f"An谩lisis base guardado con ID: {base_id}")
except Exception as e:
st.error("Error procesando texto base")
logger.error(f"Error en an谩lisis base: {str(e)}")
# Mostrar el arco base, si existe
if arc_state["base_diagram"]:
st.markdown("<hr class='divider'>", unsafe_allow_html=True)
st.markdown("#### Diagrama de Arco (Texto Base)")
st.write(arc_state["base_diagram"], unsafe_allow_html=True)
# ------------------- PESTA脩A 2: Iteraciones -------------------------
with tabs[1]:
st.subheader("An谩lisis de Cambios / Iteraciones")
# Si no se ha analizado nada en la primera pesta帽a
if not arc_state["base_id"]:
st.info("Primero analiza un texto base en la pesta帽a anterior.")
return
# Mostrar el texto base como referencia, en modo solo lectura
st.text_area(
"Texto Base (solo lectura)",
value=arc_state["base_text"],
key="base_text_ref",
height=80,
disabled=True
)
# Texto de iteraci贸n
arc_state["iteration_text"] = st.text_area(
"Texto de Iteraci贸n",
value=arc_state["iteration_text"],
key="iteration_text_input",
height=120
)
# Bot贸n para analizar iteraci贸n
if st.button("Analizar Cambios", key="btn_analyze_iteration"):
if not arc_state["iteration_text"].strip():
st.warning("Ingrese texto de iteraci贸n.")
else:
try:
# Procesar con spaCy
doc_iter = nlp_models[lang_code](arc_state["iteration_text"])
iteration_arc_html = display_arc_diagram(doc_iter)
arc_state["iteration_diagram"] = iteration_arc_html
# Guardar en BD
iteration_analysis = perform_advanced_morphosyntactic_analysis(
arc_state["iteration_text"],
nlp_models[lang_code]
)
iteration_id = store_student_morphosyntax_iteration(
username=st.session_state.username,
base_id=arc_state["base_id"],
original_text=arc_state["base_text"],
iteration_text=arc_state["iteration_text"],
arc_diagrams=iteration_analysis["arc_diagrams"]
)
if iteration_id:
st.success(f"Iteraci贸n guardada con ID: {iteration_id}")
except Exception as e:
st.error("Error procesando iteraci贸n")
logger.error(f"Error en iteraci贸n: {str(e)}")
# Mostrar el arco de iteraci贸n, si existe
if arc_state["iteration_diagram"]:
st.markdown("<hr class='divider'>", unsafe_allow_html=True)
st.markdown("#### Diagrama de Arco (Iteraci贸n)")
st.write(arc_state["iteration_diagram"], unsafe_allow_html=True)
# Mostrar comparaci贸n (opcional)
if arc_state["base_diagram"] and arc_state["iteration_diagram"]:
st.markdown("<hr class='divider'>", unsafe_allow_html=True)
st.markdown("### Comparaci贸n de Diagrama Base vs. Iteraci贸n")
col_base, col_iter = st.columns(2)
with col_base:
st.markdown("**Diagrama Base**")
st.write(arc_state["base_diagram"], unsafe_allow_html=True)
with col_iter:
st.markdown("**Diagrama Iterado**")
st.write(arc_state["iteration_diagram"], unsafe_allow_html=True)