đȘ 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.
Boostez le développement de vos applis data !
Corentin DUCLOUX
20/03/2024
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
.
Objectif : Simplifier au maximum le dĂ©veloppement dâapplications Data.
User Interface ?
Inputs ?
Outputs ?
Interactions ?
Callbacks ?
Et pourquoi pas juste un script ?
â Lançons la dĂ©mo pour voir de quoi Streamlit est capable.
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 :
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
IdentitĂ© DâEuler
eiÏ+1=0
Ajoutons ces quelques lignes de code.
Testons quelques widgets !
st.selectbox()
st.button()
st.columns()
â Colonnesst.container()
â Conteneurst.expander()
â Expandeurst.tabs()
â Tabsst.sidebar()
â Sidebarst.popover()
â Popovercolonne_1, colonne_2 = st.columns(2)
Explication visuelle par Donald J. Trump
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)
)
On va ajouter quelques onglets (Tabs) Ă notre application pour diversifier lâinterface.
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="â
")
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
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
Deux décorateurs trÚs utiles :
@st.cache_data
et @st.cache_resource
@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.
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.
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()
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
.
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()
API Reference : https://docs.streamlit.io/library/api-reference