st.progress: barra de progreso
La barra de progreso es el componente visual más directo para comunicar al usuario el avance de una operación larga. st.progress acepta un valor entre 0.0 y 1.0 (o entre 0 y 100 como entero) y un texto descriptivo opcional que se muestra encima de la barra.
El patrón habitual consiste en crear la barra antes del bucle de procesamiento, actualizarla en cada iteración con el porcentaje completado y, opcionalmente, limpiarla al finalizar con el método .empty():
import streamlit as st
import time
if st.button("Procesar datos"):
barra = st.progress(0, text="Iniciando procesamiento...")
for i in range(100):
time.sleep(0.05)
porcentaje = (i + 1) / 100
if porcentaje < 0.33:
texto = f"Cargando datos... {i+1}%"
elif porcentaje < 0.66:
texto = f"Procesando registros... {i+1}%"
else:
texto = f"Guardando resultados... {i+1}%"
barra.progress(porcentaje, text=texto)
barra.empty() # Ocultar la barra al completar
st.success("Procesamiento completado.")
El método
barra.empty()elimina la barra de la interfaz una vez finalizado el proceso. Esto es opcional, pero mejora la experiencia visual al evitar que la barra permanezca al 100% de forma indefinida.
flowchart TD
A[Operación larga en background] --> B{"Tipo de feedback?"}
B -->|Porcentaje preciso| C[st.progress 0 a 100]
B -->|Tarea indeterminada| D[st.spinner mensaje]
B -->|Pipeline multi paso| E[st.status with bloque]
B -->|Aviso temporal| F[st.toast icono]
C --> G[Bucle actualiza barra]
D --> H[with bloque mientras carga]
E --> I[update label state running success]
F --> J[Snackbar tres a cinco segundos]
G --> K[UI informa avance preciso]
H --> K
I --> K
J --> L[Confirmación no bloqueante]
K --> M[Usuario sabe que la app trabaja]
st.spinner: indicador de actividad genérico
st.spinner muestra un icono giratorio con un mensaje mientras se ejecuta el bloque de código contenido en su contexto with. A diferencia de st.progress, no requiere indicar un porcentaje: simplemente señala que la aplicación está trabajando. Es la opción preferida cuando no se conoce de antemano la duración o el número de pasos de la operación.
import streamlit as st
import time
# Spinner básico
with st.spinner("Cargando el modelo de ML..."):
time.sleep(3)
modelo_cargado = True
st.success("Modelo listo para predicciones.")
# Spinner durante consulta a base de datos
if st.button("Actualizar datos"):
with st.spinner("Consultando la base de datos..."):
time.sleep(2)
st.success("Datos actualizados.")
st.rerun()
El mensaje de texto que acompaña al spinner debe ser descriptivo y específico. En lugar de "Cargando...", es preferible indicar qué se está haciendo: "Entrenando el modelo Random Forest..." o "Consultando la base de datos de ventas...".
st.status: progreso de pipeline con pasos
st.status es ideal para mostrar el progreso de una operación con múltiples etapas claramente diferenciadas:
import streamlit as st
import time
def pipeline_ml():
with st.status("Ejecutando pipeline de ML...", expanded=True) as status:
st.write("📂 Cargando datos desde la base de datos...")
time.sleep(1.5)
st.write("✅ Datos cargados: 50.000 registros.")
st.write("🔧 Preprocesando y normalizando...")
time.sleep(1)
st.write("✅ Preprocesamiento completado.")
st.write("🧠 Entrenando el modelo Random Forest...")
time.sleep(2.5)
st.write("✅ Entrenamiento completado.")
st.write("📊 Evaluando en conjunto de test...")
time.sleep(1)
st.write("✅ AUC-ROC = 0.9431")
st.write("💾 Guardando el modelo...")
time.sleep(0.5)
# Cambiar el estado final del status container
status.update(
label="Pipeline completado exitosamente.",
state="complete",
expanded=False # Colapsar el status al terminar
)
if st.button("Ejecutar pipeline", type="primary"):
pipeline_ml()
st.metric("AUC-ROC final", "0.9431", "+0.0215 vs baseline")
El parámetro state de status.update() acepta:
"running"(predeterminado): icono de carga giratorio."complete": icono de check verde."error": icono de error rojo.
st.toast: notificaciones temporales
st.toast muestra una notificación flotante (tipo snackbar) en la esquina inferior derecha de la pantalla que desaparece automáticamente tras unos segundos. A diferencia de st.success o st.info, no ocupa espacio permanente en el flujo de la página, lo que la convierte en la opción ideal para confirmaciones rápidas que no interrumpan la lectura del contenido principal.
import streamlit as st
if st.button("Guardar cambios"):
# ... lógica de guardado
st.toast("Cambios guardados correctamente", icon="✅")
if st.button("Enviar por email"):
# ... lógica de envío
st.toast("Email enviado a usuario@empresa.com", icon="📧")
# Toast de error
if st.button("Acción con error"):
st.toast("No se pudo conectar con el servidor", icon="⚠️")
Las notificaciones toast son no bloqueantes: el usuario puede seguir interactuando con la aplicación mientras se muestran. Esto las diferencia de los mensajes de estado (
st.success,st.warning), que se insertan en el flujo del contenido y permanecen visibles hasta el siguiente rerun.
Combinación: flujo completo con retroalimentación
import streamlit as st
import time
import numpy as np
import pandas as pd
st.title("Procesador de archivos CSV")
archivo = st.file_uploader("Sube un archivo CSV", type="csv")
if archivo and st.button("Analizar y exportar", type="primary"):
barra = st.progress(0, text="Leyendo archivo...")
time.sleep(0.5)
df = pd.read_csv(archivo)
barra.progress(0.25, text=f"Archivo cargado: {len(df):,} filas.")
time.sleep(0.3)
with st.status("Procesando...", expanded=True) as status:
st.write(f"Filas: {len(df):,} | Columnas: {len(df.columns)}")
st.write("Analizando valores nulos...")
barra.progress(0.5, text="Analizando datos...")
time.sleep(0.5)
nulos = df.isnull().sum().sum()
st.write(f"Valores nulos: {nulos:,}")
st.write("Calculando estadísticas...")
barra.progress(0.75, text="Calculando estadísticas...")
time.sleep(0.5)
st.write("Exportando resultados...")
barra.progress(1.0, text="Completado.")
time.sleep(0.3)
status.update(label="Análisis completado.", state="complete", expanded=False)
barra.empty()
st.subheader("Resumen estadístico")
st.dataframe(df.describe(), use_container_width=True)
csv_export = df.describe().to_csv().encode("utf-8")
st.download_button("Descargar resumen CSV", csv_export, "resumen.csv", "text/csv")
st.toast("Análisis completado. Descarga disponible.", icon="🎉")
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Streamlit es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Streamlit
Explora más contenido relacionado con Streamlit y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Mostrar barras de progreso con st.progress durante operaciones largas. Usar st.spinner como indicador de actividad genérico mientras carga. Implementar st.status para mostrar el progreso de un pipeline con múltiples pasos. Mostrar notificaciones temporales no bloqueantes con st.toast. Combinar estos componentes para crear experiencias de usuario profesionales.