Streamlit-Tutorial: Webbasierte Python-Daten-Apps leicht gemacht
Schleusen auf für datenfokussierte Python-Anwendungen: Streamlit befähigt Entwickler, Apps dieser Art ganz ohne Frontend-Erfahrung in nur wenigen Minuten zu erstellen und zu teilen.
Foto: isabel kendzior | shutterstock.com
Ein gängiges Problem mit Python-Apps ist, sie mit anderen Menschen zu teilen. Bislang verlassen sich Developer zu diesem Zweck vor allem auf Web Interfaces, die die Funktionalitäten der Anwendung über eine Benutzeroberfläche abbilden. Das funktioniert allerdings nur wirklich gut, wenn das User Interface der App für Web-Komponenten ausgelegt ist. Leisten können das beispielsweise Data-Exploration-Anwendungen. Diese erfordern aber auch Frontend-Komponenten, die im Sinne der Interaktivität idealerweise in JavaScript geschrieben sind.
Die quelloffene Python-Bibliothek Streamlit zielt darauf ab, die meisten dieser Problemstellungen aufzulösen: Sie ermöglicht es Entwicklern, Python-Apps mit webbasierten Frontends zu entwickeln und dafür auf eine reichhaltige Sammlung interaktiver Komponenten zurückzugreifen. Resultierende Anwendungen können überall dort gehostet werden, wo auch Python-Web-Apps “leben”. Das Beste ist jedoch, dass weder HTML- noch JavaScript- oder CSS-Skills nötig sind, um überzeugende Ergebnisse zu erzielen. Stattdessen genügt Python-Code, der die Methoden und Klassen von Streamlit nutzt.
Streamlit-Beispiele
Streamlit-Programme werden in einem deklarativen Stil geschrieben. Die Objekte werden auf der Webseite in der Reihenfolge angezeigt, in der sie innerhalb des Codes deklariert sind. Jede Interaktion mit den Komponenten führt dazu, dass das Programm “top down” neu ausgeführt und die Web Page neu geladen wird, um die vorgenommenen Änderungen widerzuspiegeln.
Ein simples Streamlit-Beispiel
Zunächst ein simples Beispiel für eine Streamlit-Anwendung:
import streamlit as st
st.title("Take input from the user")
user_input = st.text_input("Say something:")
if user_input:
st.write("You said:", user_input)
Wenn Sie diesen Code mit Streamlit ausführen (streamlit run), spielt sich folgendes ab:
Eine Webseite mit dem Titel “Take input from the user” erscheint.
Darunter ist ein mit “Say something:” befülltes Textfeld zu sehen.
Wenn ein User etwas in das Textfeld eingibt und abschickt, erscheint der User Input unter dem Textfeld “You said:“.
Diese HTML-Widgets (und wie sie sich verhalten) werden von Streamlit automatisch generiert und gemanagt. Das beinhaltet auch den State der Anwendung: Das if-Statement sorgt beispielsweise dafür, dass die user_input-Textbox nur bei einer entsprechenden Eingabe anspringt.
Streamlit bietet viele weitere HTML-Komponenten. Zu den nativ verfügbaren Komponenten gehören zum Beispiel:
LaTeX-formattierter Text,
Bokeh-Charts und
Camera Input.
Ein komplexes Streamlit-Beispiel
Ein gutes Beispiel für eine komplexere Streamlit-Anwendung hält die offizielle Dokumentation des Tools bereit. Das Beispiel demonstriert dabei eindrücklich, was Streamlit an diversen Fronten leisten kann. Zu diesem Zweck wird ein gängiges Datenset eingesetzt (Uber-Fahrtantritte und -Abschlüsse in Manhattan, kategorisiert nach Stunden). Die entsprechenden Zeiten werden in einem Balkendiagramm, die jeweiligen Standorte über eine interaktive Karte visualisiert.
Das gesamte Programm besteht dabei aus nur etwa 30 Code-Zeilen. Das ist kompakt genug, um es im Copy-Paste-Verfahren in eine Datei einzufügen und zu experimentieren.
Daten in Streamlit-Anwendungen
Streamlit bietet auch diverse native Wege, um mit Datenquellen umzugehen. Dataframes dienen dabei als primäres Format, um Daten zu laden und mit ihnen zu arbeiten.
Sie können jedoch auch Daten aus jeder anderen Quelle laden, die sie auch in anderen Python-Apps nutzen würden. Um diesen Prozess zu unterstützen, bietet Streamlit weitere Annehmlichkeiten: Die Datenvisualisierungs-Anwendung aus dem vorhergehenden Abschnitt nutzt etwa Pandas, um eine .CSV-Datei über eine Remote-URL zu laden und in einen Dataframe zu transformieren. Das ist zwar komfortabel, wenn es darum geht, Daten zu laden und zu formatieren, kann aber auch viel Zeit kosten – insbesondere, wenn dazu eine Netzwerkverbindung genutzt wird. Darüber hinaus muss das Programm auch nach jeder User-Aktion neu laden.
Um dieses Problem zu umgehen, bietet Streamlit den Decorator @st.cache_data, der genutzt wird, um die load_data()-Funktion zu wrappen. Zudem werden Daten über @st.cache_data über mehrere Reloads hinweg zwischengespeichert, so dass diese nur einmal nach jedem App-Start geladen werden.
State Management mit Streamlit
Weil das Design von Streamlit Applikationen nach jeder User-Interaktion zum Reload zwingt, ist es nicht unbedingt selbsterklärend, wie man eine Anwendung in einem Persistent State hält. Eingangs haben wir betrachtet, wie Daten in einem Textfeld den State zwischen den Runs händeln. Wollen Sie nun den State unabhängig von einzelnen Kontrollelementen erstellen und managen, müssen Sie auf das in Streamlit integrierte session_state-Objekt zurückgreifen.
Bei streamlit.session_state handelt es sich um einen Key-Value-Store (im Wesentlichen ein Dictionary), der über mehrere Durchläufe hinweg persistent bleibt. Wenn ein Streamlit-Programm zum ersten Mal gestartet wird, ist dieser Store leer. Sie müssen also überprüfen ob Keys vorhanden sind, bevor sie versuchen auf diese zuzugreifen.
import streamlit as st
# create the key "sayings" if it doesn't exist
if 'sayings' not in st.session_state:
st.session_state['sayings'] = []
# for convenience, make a reference
sayings = st.session_state['sayings']
st.title("Take input from the user")
user_input = st.text_input("Say something:")
if sayings:
# display "sayings" if it has inputs from previous runs
st.write("You previously said:", sayings)
if user_input:
# add to "sayings" if we get an input
sayings.append(user_input)
st.write("You said:", user_input)
Dabei sollten Sie beachten, dass alle Daten, die in session_state gespeichert werden, nur über die Lebensdauer des Streamlit-Servers, auf dem die Anwendung läuft, bestehen bleiben. Ist der Server weg, gehen auch die Daten verloren. Wenn Sie eine aggressivere Datenpersistenz wünschen, müssen Sie mögicherweise auf eine Datenbank-Lösung oder einen In-Memory-Cache wie Redis zurückgreifen.
Data Widgets für Streamlit-Applikationen
Streamlit-Steuerelemente um Interaktionen von oder mit Daten anzuzeigen, sind bereits von Grund auf darauf konzipiert, Informationen für die gängigsten Use Cases zu zu rendern. Streamlit Web Widgets können beispielsweise Dataframes als Quelle nutzen und diese automatisiert mit den richtigen Spaltenbeschriftung bestücken, so dass es Ihnen erspart bleibt, das manuell zu erledigen.
Standardmäßig enthält Streamlit eine breite Palette gängiger Daten-Widgets. Weitere solcher Komponenten stehen zudem über die Community zur Verfügung und sind nur einen pip install-Befehl entfernt.
Streamlit-Apps bereitstellen
Weil es sich bei Streamlit-Anwendungen im Kern um Python-Web-Apps handelt, können sie auf die gleiche Weise bereitgestellt werden wie jede andere, vernetzte Python-Anwendung. Die Anwendung auf einem bestimmten Rechner auszuführen und über den zugewiesenen Port Zugriff darauf zu gewähren, wäre diesbezüglich die Quick-and-Dirty-Strategie.
Doch auch fortschrittlichere Deployments folgen dem Muster anderer Python-Webanwendungen – und lassen sich etwa mit Docker, Kubernetes oder anderen gängigen Cloud Services stemmen. Auch Snowflake-Anwender können Streamlit-Apps über AWS und Azure bereitstellen – unterstützt durch den entsprechenden Data Store. Last, but not least gibt es auch noch einen eigenen Community-Cloud-Hosting-Service von Streamlit, der für die zugehörigen Applikationen jedoch nicht obligatorisch ist. (fm)
Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!
Hier finden Sie den kompletten Artikel: