aim-dashboard / app.py
Tefifi's picture
Correccion nltk
14575c8
"""
AIM Dashboard β€” Punto de entrada principal.
Ejecutar con: python app.py
"""
import nltk
nltk.download('punkt', quiet=True)
nltk.download('punkt_tab', quiet=True)
import logging
import dash
import dash_bootstrap_components as dbc
from dash import dcc, html
from layouts.pages import layout_home, all_layouts
from callbacks.navegacion import registrar_callbacks
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
app = dash.Dash(
__name__,
suppress_callback_exceptions=True,
external_stylesheets=[dbc.themes.BOOTSTRAP],
meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}],
)
app.title = "AIM Dashboard"
# ── Panel de progreso en el layout raΓ­z ──────────────────────────────────────
# Debe estar aquΓ­ (no en page-content) para que los callbacks siempre
# puedan escribir en Γ©l sin importar quΓ© pΓ‘gina estΓ‘ cargada.
# Se muestra como barra fija en la parte inferior de la pantalla.
panel_progreso = html.Div(
id="panel-progreso",
style={"display": "none"},
children=[
html.Div(
style={
"position": "fixed",
"bottom": "0", "left": "0", "right": "0",
"zIndex": "1000",
"background": "#ffffff",
"borderTop": "3px solid #1c3160",
"boxShadow": "0 -4px 24px rgba(28,49,96,0.15)",
"padding": "18px 36px 20px",
},
children=[
html.Div(
style={"maxWidth": "860px", "margin": "0 auto"},
children=[
html.Div(
style={"display": "flex", "alignItems": "center",
"justifyContent": "space-between", "marginBottom": "10px"},
children=[
html.Span("Analizando perfil AIM", style={
"fontSize": "0.78rem", "fontWeight": "700",
"letterSpacing": "1.2px", "textTransform": "uppercase",
"color": "#1c3160",
}),
html.Span(id="progreso-pct", style={
"fontSize": "1rem", "fontWeight": "700",
"color": "#b87a2a",
}),
],
),
html.Div(
style={
"background": "#e8ecf2",
"borderRadius": "999px",
"height": "14px",
"marginBottom": "14px",
"overflow": "hidden",
"border": "2px solid #b0bacb",
"boxShadow": "inset 0 1px 3px rgba(0,0,0,0.1)",
},
children=[
html.Div(
id="progreso-bar",
style={
"height": "100%", "borderRadius": "999px",
"background": "linear-gradient(90deg, #b87a2a, #d4a843)",
"width": "0%",
"transition": "width 0.8s ease",
"boxShadow": "0 1px 4px rgba(184,122,42,0.4)",
},
)
],
),
html.Div(id="progreso-container"),
html.Div(id="error-msg", children=""),
],
)
],
)
],
)
# ── Layout raΓ­z ───────────────────────────────────────────────────────────────
app.layout = html.Div([
dcc.Location(id="url", refresh=False),
dcc.Store(id="store_name", storage_type="session"),
dcc.Store(id="store_link", storage_type="session"),
dcc.Interval(id="interval_progress", interval=600, n_intervals=0, disabled=True),
html.Div(id="page-content"),
panel_progreso,
])
# ── Routing ───────────────────────────────────────────────────────────────────
@app.callback(
dash.Output("page-content", "children"),
dash.Input("url", "pathname"),
)
def mostrar_pagina(pathname: str):
rutas = {
"/profile_1": all_layouts[0],
"/profile_2": all_layouts[1],
"/profile_3": all_layouts[2],
"/profile_4": all_layouts[3],
"/profile_5": all_layouts[4],
}
return rutas.get(pathname, layout_home)
registrar_callbacks(app)
server = app.server # para Gunicorn: gunicorn app:server
if __name__ == "__main__":
app.run(debug=False, host="0.0.0.0", port=8050)