streamlit4dummies

Parte 2 - Practical Kindom

Nuestro héroe perfecciona sus habilidades y triunfa sobre el desafío

1. Actividad Práctica: Analizando un archivo cargado por usuario

Completar el archivo pages/01_📃_Archivo.py para que, usando la librería pandas y matplotlib, permita:

En ./datasets/ existen 2 datasets para testear la actividad: ExhaustiveDinosaurDataset.csv y CoffeeQuantityDataset.csv, pero puedes probar con otros datasets.

2. Session State

Considera el siguiente código a ejecutar en streamlit:

c1, c2 = st.columns([1,2])
has_clicked = c1.button("Haz Click")
if has_clicked:
    c2.write("Presionaste el boton!!!")
else:
    c2.write("No has hecho presionado el boton")

Al ejecutarlo, funciona tal como esperabas. Por defecto, st.button regresa el valor False y al hacer click en él, cambia a True (y se actualiza el mensaje).

Tomemos ahora un ejemplo un poco distinto:

c1, c2 = st.columns([1, 2])
has_clicked = c1.button("Haz Click")
number_of_clicks = 0
if has_clicked:
    number_of_clicks += 1
    c2.write(f"Has presionado el boton!!!. Número de clicks: {number_of_clicks}")
else:
    c2.write("No has presionado el boton")

El código anterior NO funciona para que el usuario pueda saber cuantas veces ha hecho click en el botón. ¿Porqué? Porque Streamlit ejecuta el script de nuevo cada vez que se carga la página, por lo que el valor de number_of_clicks se resetea a 0.

Para solucionar este problema, podemos usar session_state de Streamlit. Puedes imaginar st.session_state como un diccionario que es persistente en la sesión del usuario. Puedes poner en este diccionario cualquier elemento que quieras, pero ¡ten cuidado de asegurarte que inicializarlo con un valor inicial!

Arreglemos el ejemplo:

c1, c2 = st.columns([1, 2])
has_clicked = c1.button("Haz Click")
if "number_of_clicks" not in st.session_state:
    st.session_state["number_of_clicks"] = 0
if has_clicked:
    st.session_state["number_of_clicks"] += 1
    c2.write(f"Has presionado el boton!!!. Número de clicks: {st.session_state.number_of_clicks}")
else:
    c2.write("No has presionado el boton")

Puedes aprender más de session_state en Session State API reference.

5. Optimization

A esta altura te habrás dado cuenta que Streamlit no es super veloz. Por ello, algunos trucos te ayudarán a que la experiencia de usuario sea un poco más fluída.

Consideremos el siguiente ejemplo - ejecútalo!

import streamlit as st
import time

def funcion_inevitablemente_lenta(a, b):
    time.sleep(2)
    return a * b

c1, c2, c3, c4 = st.columns([1, 1, 1, 2])
a = int(c1.text_input("a", value=1))
b = int(c2.text_input("b", value=2))
axb = funcion_inevitablemente_lenta(a, b)
c4.title(f"{a} * {b} = {axb}")

Al probar distintas combinaciones, vemos que la función es muy lenta. Al probar una combinación ya probada anteriormente, la función se ejecuta de nuevo.

Compara ahora con el siguiente ejemplo:

import streamlit as st
import time

@st.cache()
def funcion_inevitablemente_lenta(a, b):
    time.sleep(2)
    return a * b

c1, c2, c3, c4 = st.columns([1, 1, 1, 2])
a = int(c1.text_input("a", value=1))
b = int(c2.text_input("b", value=2))
axb = funcion_inevitablemente_lenta(a, b)
c4.title(f"{a} * {b} = {axb}")

En este caso, hemos simplemente agregado @st.cache a la función. Esto significa que cada ejecución de la función se guarda en memoria, considerando sus argumentos como parte de la clave (además de otras cosas). Si vuelves a pedir la ejecución de la función para valores que ya son conocidos, se carga directamente de la memoria y no se ejecuta de nuevo.

Puedes aprender más de optimización de rendimiento en Optimize performance with st.cache, y en Performance Optimization Methods.

3. Secrets

Nunca es aconsejable guardar contraseñas o información de tarjeta de crédito en el código (escribiéndolas directamente como variables) o en el repositorio (escribiéndolas en un archivo). Para solucionar este problema, Streamlit propociona un diccionario llamado st.secrets. ¿Como funciona? Muy simple:

El formato de secrets.toml es un archivo de configuración de [TOML], que es muy similar a python. Por ejemplo, podría contener la siguiente línea:

# Este es un comentario
db_username = "Jane" 
db_password = "12345qwerty"

Puedes acceder a los valores disponibles en st.secrets como si fuera un diccionario:

st.write("Usuario:", st.secrets.db_username)
st.write("Password:", st.secrets.db_password)

Puedes aprender más al respecto en Secrets Management.

4. Query parameters

Cada vez tenemos más herramientas a nuestra disposición.

Una funcionalidad adicional que puede ser útil, es la de recuperar los parámetros de la URL. Esto puede usarse para consumir una API, o incluso esconder “Easter Eggs”.

Puedes acceder a los query parameters usando lo siguiente:

query_params = st.experimental_get_query_params() # Obtener los parametros
st.write(query_params) # Imprimir el diccionario
st.write(query_params["selected"][0]) # Imprimir el primer elemento para el parametro "show_map"

Prueba que pasa con algunas urls como:

Importante: Los valores que regresa el diccionario para cada llave son siempre una lista, aunque el usuario haya entregado un único valor. Esto tiene sentido porque potencialmente el usuario puede entregar más de un valor para una misma llave.

De manera complementaria, si después de procesar ciertos parámetros, quieres volver a redirigir al usuario a una url con ciertos parametros, puedes usar la función st.experimental_set_query_params.

Para llevar al usuario a la url http://localhost:8501/?show_parenthesis=False&selected=Pycon&selected=Chile, deberías hacer lo siguiente:

query_params = {"show_parenthesis":False, "selected": ["Pycon", "Chile"]} # Parámetros de la URL
st.experimental_set_query_params(**query_params) # Redirigimos a la página con los parámetros

Intenta probar el código anterior estando en la dirección http://localhost:8501/ y viendo como la redirección ocurre automáticamente.

Es importante notar que los parámetros de la URL se mantendrán aunque navegues a otras páginas de la misma aplicación. Eso puede ser bueno o malo dependiendo de tu aplicación.

6. Streamlit components

Los componentes son extensiones realizados por la comunidad, pero no directamente por Streamlit. Algunos componentes han terminado por integrarse a Streamlit, cuando la funcionalidad es importante o muy útil.

En el siguiente enlace puedes encontrar la lista oficial de Componentes mientras que en este otro enlace, está la lista no oficial de componentes.

Hay muchos ejemplos, pero los más interesantes son los siguientes:

En muchos casos, los componentes son una forma de empaquetar una funcionalidad o librería que ya existe en html/javascript, y lograr que pueda llamarse de manera nativa en Streamlit. No creo que inicialmente necesites un componente, pero siempre conviene mirar en la lista si hay alguna funcionalidad que necesitas en tu proyecto.

Puedes encontrar la información oficial en Streamlit Components.

7. Actividad Práctica: Consumiendo un API

Una API es una mecanismo de conectarse con un computador y lograr que haga cosas: entregar información (método GET), recibir información (método POST), etc.

API

Algunos ejemplos de API:

En esta actividad, completaremos la información de la pagina web con información que obtendremos una API. La API que usaremos es la de dog.ceo.

Editar el archivo pages/02_🌐_API.py para que:

8. Seguir aprendiendo

Consejos:

Comunidades:

📖 Libros:

Twitter:

LINKS