đŸȘ Mon site web utilise des cookies

Ces cookies sont uniquement destinés à des fins d'analyse du trafic sur mon site, et sont entiÚrement optionnels.

đŸ’» Streamlit

Boostez le développement de vos applis data !

Corentin DUCLOUX

20/03/2024

Présentation

Un framework python récent, lancé en 2019.

Et avant Streamlit, qu’est ce qu’il y avait ?

  • Flask ⇒ Prise en main trĂšs complexe, plus adaptĂ©e pour les Software Engineers.

  • Plotly Dash ⇒ Prise en main plus simple que Flask, concept assez similaire Ă  Shiny avec sĂ©paration des composants UI et server.

Corentin

  • Flask ⇒ Super Framework pour faire une appli web scalable mais si vous venez d’un background Data c’est vraiment trĂšs trĂšs galĂšre, il faut savoir ce qu’on fait.

  • Plotly Dash ⇒ Configuration des inputs, outputs, callbacks.

Pourquoi Streamlit ?

Objectif : Simplifier au maximum le dĂ©veloppement d’applications Data.

User Interface ?

Inputs ?

Outputs ?

Interactions ?

Callbacks ?

Et pourquoi pas juste un script ?

Corentin

A dire aprùs l’objectif :

A l’époque un Data Scientist il faisait son petit Boosting en utilisant sklearn, il faisait une cross-validation, il regardait ses mĂ©triques et puis si c’était bien il passait Ă  un autre projet.

Et puis
c’est tout.

En bref il restait souvent dans son notebook, le modĂšle Ă©tait assez peu exploitable, et surtout, il Ă©tait interprĂ©table uniquement par les Ă©quipes Data qui l’avaient fait. Et les Data Scientists ils avaient pas particuliĂšrement envie de s’embĂȘter Ă  apprendre Dash ou mĂȘme Flask. Niveau communication des rĂ©sultats on a vu mieux.

Et c’est lĂ  que Streamlit arrive avec une idĂ©e toute simple : au lieu de sĂ©parer tous les composants logiciels de l’interface utilisateur, on fait juste un script.

Installation

On passe à l’installation ?

  1. Lancement d’un terminal :
  2. Et ensuite on installe via pip avec la commande
python -m pip install streamlit

Aybuké

Est-ce que tt le monde a réussi à installer du coup ?

Prise en main

⇒ Lançons la dĂ©mo pour voir de quoi Streamlit est capable.

👋 Hello Streamlit

python -m streamlit hello

Aybuké

Vous pouvez regarder en dĂ©tail la dĂ©mo mais on va pas vraiment se concentrer dessus Ă©tant donnĂ© qu’on va construire une petite app nous-mĂȘme, on trouve que c’est quand mĂȘme plus intĂ©ressant.

Un premier jet !

app.py
import streamlit as st

st.set_page_config(page_icon="🐍", page_title="PyApp")
st.title("😎 Ma premiĂšre app super stylĂ©e")

st.markdown("Du *markdown* dans l'app ? **Rien de plus simple !**")
st.markdown("- Lien vers [`streamlit`](https://streamlit.io/)")
st.markdown(
    """
    > Des couleurs ? :orange[orange], :red[rouge], :green[vert]
    """
)

st.code(
    """
    [[i for i in range(5)] for j in range(2)] 
    # Du code non-exécutable
    """,
    language="python"
)

st.divider()

🚀 et pour lancer l’appli :

python -m streamlit run app.py

Aybuké

Ce qu’on a vu jusqu’ici

  • st.set_page_config() pour configurer le favicon et le titre de l’onglet dans le navigateur

  • st.title() pour donner un titre Ă  notre app

  • st.markdown() pour ajouter du texte avec diffĂ©rents types de formattage : italique, gras, ajout de liens, etc.

  • st.code() pour inclure du code non-exĂ©cutable provenant de diffĂ©rents langages : python, SQL, CSS, etc.

  • st.divider() pour tracer une ligne horizontale

Aybuké

Intégration de LaTeX

IdentitĂ© D’Euler

eiπ+1=0

Ajoutons ces quelques lignes de code.

st.header("Ajoutons du LaTeX")
st.subheader("Identité d'*Euler*", divider="blue")
st.latex("e^{i \pi} + 1 = 0")
st.caption(
    """
    L'identité d'*Euler* est souvent citée comme
    un exemple de beauté mathématique.
    """
)

Présentation de widgets

Testons quelques widgets !

  • st.selectbox()
  • st.button()
fruit = st.selectbox(
    "Fruit",
    ("🍓 Fraise", "🍊 Orange", "đŸ„­ Mangue", "🍌 Banane", "🍏 Pomme"),
    index = None,
    placeholder = "Sélectionner un fruit"
)

bouton = st.button("Voir les détails du fruit sélectionné")

if bouton:
    st.write(f"T'as la dalle ! Tu veux manger une **{fruit}**")

Guillaume

Notez qu’une fois que vous changez l’input de la selectbox dans l’application, l’ensemble du script est rĂ©-Ă©xĂ©cutĂ©, et donc, le bouton est re-cachĂ© par dĂ©faut.

Ce rerun total qui est la signature de streamlit peut faciliter le dĂ©veloppement de certaines applis mais peut parfois ĂȘtre assez contraignant.

Options de layout

  • st.columns() ⇒ Colonnes
  • st.container() ⇒ Conteneur
  • st.expander() ⇒ Expandeur
  • st.tabs() ⇒ Tabs
  • st.sidebar() ⇒ Sidebar
  • st.popover() ⇒ Popover

Hassan

De nombreuses options de layout sont disponibles pour modifier l’application.

On peut ajouter des colonnes, créer des boites flexbox avec les containers, des tabs, une sidebar, etc.

Colonnes

colonne_1, colonne_2 = st.columns(2)

Explication visuelle par Donald J. Trump

Hassan

La je vais d’abord vous prĂ©senter la crĂ©ation de colonnes avec le futur prĂ©sident des Etats-Unis.

Il y a plusieurs moyens de gĂ©rer la taille des colonnes, par dĂ©faut si on ne met qu’un chiffre qui indique le nombre de colonnes ça va diviser la page en 2,3,4, etc.

Mais on peut aussi passer une liste avec des floats du type [0.1, 0.4, 0.4, 0.1]

Sidebar

On va changer notre interface utilisateur pour ajouter une Sidebar et regrouper nos widgets.

with st.sidebar:
    prenom = st.text_input("đŸ€  Ecris ton prĂ©nom *cow-boy* !")
    reussite = st.checkbox("Tu penses avoir ton année ?")
    note_pf = st.number_input(
        "Ta note en Concurrence et Innovation",
        min_value=0,
        max_value=5,
        step=1
    )
    epanouissement = st.select_slider(
        "Ton épanouissement en master",
        range(11)
    )

Aybuké

La notation with permet de dire avec quel objet du layout on travaille. La, on voit qu’on travaille avec notre sidebar et qu’on lui ajoute des inputs.

Tabs

On va ajouter quelques onglets (Tabs) à notre application pour diversifier l’interface.

tab_1, tab_2, tab_3 = st.tabs(
    ["🔎 Infos sur l'annĂ©e", "📄 DataFrame", "📊 Graphiques"]
)

if prenom:
    with tab_1:
        if reussite:
            st.balloons()
            st.write(f"FĂ©licitations pour ton annĂ©e *{prenom}* ! 🎈")
        else:
            st.snow()
            st.write(
                f"**Aie**... đŸ„¶ c'est un travail insuffisant *{prenom}*"
            )

Guillaume

On va en plus vous faire crouler sous les ballons et la neige maintenant.

Des messages de statut

  • â„č st.info()
  • ❌ st.error()
  • ⚠ st.warning()
  • ✅ st.success()
with st.sidebar:
    with st.expander("On regarde quelques messages ?"):
        st.info(
            f"Ton épanouissement en master : {epanouissement}/10",
            icon="đŸ‘šâ€đŸ«"
        )
        st.error(
            f"Ta note en Concurrence et Innovation : {note_pf}",
            icon="👀"
        )
        st.warning("Ceci est un avertissement gĂ©nĂ©rique", icon="⚠")
        st.success("Message de rĂ©ussite.", icon="✅")

Hassan

Sur Streamlit, il existe aussi des conteneurs colorĂ©s spĂ©ciaux qui sont adaptĂ©s pour l’affichage d’erreurs, d’infos, d’avertissements. On va les rergarder un petit peu ensemble.

Et avec des vraies données ? (I)

On a vu tout un tas d’élĂ©ments d’UI, mais on a pas vraiment interragi avec des donnĂ©es dignes de ce nom.

⇒ Morale de l’histoire : Installe polars

Corentin

Quand on pense manipulation de donnĂ©es en python, on pense pandas, mais il est temps de passer Ă  la vitesse supĂ©rieure et d’avoir un truc vraiment rapide.

Et avec des vraies données ? (II)

Exemple avec des données de cas de COVID-19 aux Etats-Unis entre 2020 et 2022 : + 2.5 millions de lignes !

import polars as pl

df_covid = pl.read_csv(
    "https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv"
)

ProblĂšmes

  • L’import met trois ans
  • En plus, chaque action dans l’appli relance l’import


Corentin

On est pas rendus


Corentin

Solution (I)

Deux décorateurs trÚs utiles :

@st.cache_data et @st.cache_resource

Corentin

Pour le premier dĂ©corateur, imaginez que vous ayez un dataframe de 2,5 millions lignes, ça va devenir assez encombrant que chaque interaction relance entiĂšrement l’appli, et donc l’import des donnĂ©es peut se faire en une fois, et ensuite les donnĂ©es vont rester dans le cache du navigateur.

Solution (II)

@st.cache_data
def import_covid_usa(link: str) -> pl.DataFrame:
    """Fonction d'import des données optimisée."""
    return pl.read_csv(link)

💡 Et maintenant, observons la diffĂ©rence !

df_covid = import_covid_usa(
    "https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv"
)

Note

On attend une seule fois pour l’import des donnĂ©es, ce qui est beaucoup plus satisfaisant pour l’utilisateur.

  • Solution la plus optimale ici : base de donnĂ©es

Corentin

Affichage d’un tableau

On a maintenant envie d’afficher nos donnĂ©es sous forme de tableau.

with tab_2:
    st.dataframe(
        df_covid,
        hide_index=True,
        use_container_width=True,
        column_config={
            "date": st.column_config.DateColumn("📅 Date", format="DD/MM/YYYY")
        },
    )

⇒ Grande flexibilitĂ© dans l’affichage.

Hassan

L’option hide_index permet de cacher la colonne d’indice qui est associĂ©e au dataframe.

La seconde option permet de forcer le tableau Ă  prendre la taille complĂšte du conteneur. La derniĂšre option est probablement la plus intĂ©ressante parce qu’elle permet de passer un schĂ©ma de configuration de colonnes pour les personnaliser.

📊 Et pour les graphiques ?

On va chercher à visualiser le nombre de morts par état à une certaine date.

with tab_3:
    st.subheader("Nombre de personnes mortes de COVID-19 *(Noël 2020)*")

    deaths_by_state_christmas = (
        df_covid.filter(pl.col("date") == "2020-12-25")
        .group_by("state")
        .agg(pl.col("deaths").sum())
    )

    st.bar_chart(deaths_by_state_christmas, x="state", y="deaths")

De nombreuses options de visualisation à la volée :

  • st.line_chart()
  • st.scatter_chart()
  • st.map()
  • etc.

Aybuké

Dans notre code ici, on retrouve un peu de polars mais rien de compliqué vous voyez que ça ressemble à la syntaxe de SQL.

Pour plus de contrîle sur les visualisations on peut utiliser plotly, altair ou matplotlib avec d’autres commandes.

DeltaGenerator

Mais comment tout ça marche ?

Au coeur de tous ces composants permettant de crĂ©er l’interface utilisateur, il y a une classe : le DeltaGenerator.

  • SystĂšme basĂ© sur protobuf, crĂ©e par GOOGLE

Corentin

Et comme évidemment les devs de chez Streamlit ils ont pas réinventé la roue ils ont utilisé un systÚme de sérialisation et désérialisation de données qui a été crée à la base par Google.

Les messages Delta protobuf dans Streamlit en gros c’est donc des messages qui dĂ©crivent les modifications Ă  apporter Ă  l’interface utilisateur de l’application. Ces messages contiennent des instructions sur la façon de mettre Ă  jour ou de modifier les Ă©lĂ©ments.

Pour aller + loin

Secrets management

def check_password():
    """Returns `True` if the user had the correct password."""

    def password_entered():
        """Checks whether a password entered by the user is correct."""
        if hmac.compare_digest(st.session_state["password"], st.secrets["password"]):
            st.session_state["password_correct"] = True
            del st.session_state["password"]  # Don't store the password.
        else:
            st.session_state["password_correct"] = False

    # Return True if the password is validated.
    if st.session_state.get("password_correct", False):
        return True

    # Show input for password.
    st.text_input(
        "Mot de passe",
        type="password",
        on_change=password_entered,
        key="password",
        placeholder="Veuillez insérer le mot de passe pour accéder à l'application.",
    )
    if "password_correct" in st.session_state:
        st.error("😕 Mot de passe incorrect")
    return False


if not check_password():
    st.stop()

Hassan

Exemples concrets

  • đŸ· Projet de Machine Learning : Wine Scraping
  • 🚗 Projet de Machine Learning : EstimyCar

API Reference : https://docs.streamlit.io/library/api-reference

Guillaume

FIN

Hassan

Streamlit devient de plus en plus omniprĂ©sent dans le domaine de la data et vous aurez peut-ĂȘtre Ă  l’utiliser, et en tout cas nous on vous le conseille fortement, et surtout on espĂšre que ça vous a plu et que ça vous sera utile.

(Un dernier meme pour la route)

Retourner vers mon site web

đŸ’» Streamlit Boostez le dĂ©veloppement de vos applis data ! Corentin DUCLOUX 20/03/2024

  1. Slides

  2. Tools

  3. Close
  • đŸ’» Streamlit
  • PrĂ©sentation
  • Pourquoi Streamlit ?
  • Installation
  • Prise en main
  • Un premier jet !
  • Ce qu’on a vu jusqu’ici
  • IntĂ©gration de LaTeX
  • PrĂ©sentation de widgets
  • Options de layout
  • Colonnes
  • Sidebar
  • Tabs
  • Des messages de statut
  • Et avec des vraies donnĂ©es ? (I)
  • Et avec des vraies donnĂ©es ? (II)
  • On est pas rendus

  • Solution (I)
  • Solution (II)
  • Affichage d’un tableau
  • 📊 Et pour les graphiques ?
  • DeltaGenerator
  • Pour aller + loin
  • Exemples concrets
  • FIN
  • (Un dernier meme pour la route)
  • f Fullscreen
  • s Speaker View
  • o Slide Overview
  • e PDF Export Mode
  • ? Keyboard Help