st.progress, st.spinner, st.status y st.toast para retroalimentación

Básico
Streamlit
Streamlit
Actualizado: 26/04/2026

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 - Autor del tutorial

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.