14 posts 57 tags 7 domains

Python i Streamlit — od skryptu do aplikacji webowej w 10 minut

Podstawy Pythona oraz Streamlit — jak zamienić zwykły skrypt w interaktywną aplikację bez HTML, CSS i JS.

Problem

Masz skrypt w Pythonie, który robi coś użytecznego — analizuje CSV, wywołuje API, liczy statystyki. Chcesz pokazać efekt komuś, kto nie odpala terminala. Klasyczne podejście to Flask/FastAPI + frontend w React. Tygodnie pracy.

Streamlit rozwiązuje to inaczej: piszesz pure Python, framework sam renderuje widżety, zarządza stanem i serwuje aplikację przez przeglądarkę. Zero HTML, CSS i JavaScriptu.

Instalacja

Wymagany Python 3.10 lub nowszy (Streamlit 1.57 wspiera 3.10–3.14).

bash
$python3 -m venv .venv
$source .venv/bin/activate
$pip install streamlit
$streamlit hello

Ostatnia komenda otwiera demo w przeglądarce — jeśli działa, jesteś gotowy.

Python — minimum, które musisz znać

Streamlit jest pythonic, więc warto ogarnąć podstawy języka. Najważniejsze konstrukcje, które pojawią się w każdej aplikacji:

Zmienne i typy

python
name = "Anna"           # str
age = 30                # int
price = 19.99           # float
active = True           # bool
tags = ["py", "web"]    # list
user = {"id": 1, "name": "Anna"}  # dict

Funkcje

python
def calculate_tax(amount: float, rate: float = 0.23) -> float:
    return amount * rate

print(calculate_tax(1000))  # 230.0

Type hints (: float, -> float) nie są wymagane, ale Streamlit z nich korzysta — np. do automatycznego dobierania widżetów.

Pętle i warunki

python
for tag in tags:
    if tag.startswith("p"):
        print(tag.upper())

Importy

python
import pandas as pd
import streamlit as st
from datetime import datetime

Konwencja import streamlit as st jest standardem — wszystkie tutoriale i dokumentacja używają tego aliasu.

Pierwsza aplikacja Streamlit

Utwórz plik app.py:

python
import streamlit as st

st.title("Moja pierwsza aplikacja")
st.write("Witaj w Streamlit!")

name = st.text_input("Jak masz na imię?")
if name:
    st.success(f"Cześć, {name}!")

Uruchom:

bash
$streamlit run app.py

Aplikacja otwiera się pod http://localhost:8501. Każda zmiana w pliku → ikona "Rerun" w prawym górnym rogu albo auto-reload.

Model wykonania — top-to-bottom

To kluczowy koncept, który myli początkujących. Streamlit re-runuje cały skrypt od góry do dołu przy każdej interakcji użytkownika. Klik w slider → cały plik wykonuje się od nowa.

python
import streamlit as st

x = st.slider("Wybierz wartość", 0, 100, 50)
st.write(f"{x} do kwadratu = {x * x}")

Brzmi nieefektywnie, ale dzięki cache'owaniu (o tym za chwilę) działa szybko.

Widżety — interaktywność w jednej linijce

Każdy widżet zwraca aktualną wartość. Bez stanu, bez subskrypcji.

python
import streamlit as st
import pandas as pd

# Podstawowe inputy
text = st.text_input("Tekst")
number = st.number_input("Liczba", min_value=0, max_value=100)
date = st.date_input("Data")
choice = st.selectbox("Wybierz", ["A", "B", "C"])
multi = st.multiselect("Wiele opcji", ["X", "Y", "Z"])
checked = st.checkbox("Zgoda")

# Slidery i przyciski
value = st.slider("Zakres", 0, 100, (20, 80))
clicked = st.button("Kliknij")

# Upload pliku
uploaded = st.file_uploader("Wgraj CSV", type="csv")
if uploaded:
    df = pd.read_csv(uploaded)
    st.dataframe(df)

Layout — kolumny, taby, sidebar

python
import streamlit as st

# Sidebar (lewy panel)
with st.sidebar:
    api_key = st.text_input("API Key", type="password")
    model = st.selectbox("Model", ["gpt-4", "claude"])

# Kolumny
col1, col2, col3 = st.columns(3)
col1.metric("Sprzedaż", "12 500 zł", "+8%")
col2.metric("Klienci", "342", "+12")
col3.metric("Konwersja", "3.4%", "-0.2%")

# Taby
tab1, tab2 = st.tabs(["Wykres", "Dane"])
with tab1:
    st.line_chart({"a": [1, 2, 3, 4]})
with tab2:
    st.write("Tu są dane")

Cache — bez tego apka będzie wolna

Skoro skrypt re-runuje się przy każdej interakcji, kosztowne operacje (pobieranie danych, ładowanie modelu ML) trzeba cache'ować.

python
import streamlit as st
import pandas as pd

@st.cache_data
def load_data(path: str) -> pd.DataFrame:
    return pd.read_csv(path)

@st.cache_resource
def load_model():
    from sklearn.ensemble import RandomForestClassifier
    # kosztowna inicjalizacja
    return RandomForestClassifier()

df = load_data("sales.csv")     # czyta raz, potem z cache
model = load_model()            # ładuje raz, współdzielone między sesjami

Różnica:

  • @st.cache_data — dla danych (DataFrame, dict, list). Każda sesja dostaje kopię.
  • @st.cache_resource — dla obiektów typu model, połączenie do bazy, klient API. Współdzielone globalnie.

Session State — kiedy potrzebujesz pamięci

Czasem trzeba zapamiętać coś między re-runami (licznik, koszyk, historia czatu):

python
import streamlit as st

if "counter" not in st.session_state:
    st.session_state.counter = 0

if st.button("Dodaj"):
    st.session_state.counter += 1

st.write(f"Licznik: {st.session_state.counter}")

Praktyczny przykład — dashboard CSV

Cała aplikacja do analizy uploadowanego pliku:

python
import streamlit as st
import pandas as pd

st.set_page_config(page_title="Analiza CSV", layout="wide")
st.title("📊 Szybka analiza CSV")

uploaded = st.file_uploader("Wgraj plik", type="csv")

if uploaded:
    df = pd.read_csv(uploaded)

    col1, col2, col3 = st.columns(3)
    col1.metric("Wiersze", len(df))
    col2.metric("Kolumny", len(df.columns))
    col3.metric("Braki", df.isna().sum().sum())

    tab1, tab2, tab3 = st.tabs(["Podgląd", "Statystyki", "Wykres"])

    with tab1:
        st.dataframe(df, use_container_width=True)

    with tab2:
        st.write(df.describe())

    with tab3:
        numeric_cols = df.select_dtypes("number").columns.tolist()
        if numeric_cols:
            col = st.selectbox("Kolumna", numeric_cols)
            st.bar_chart(df[col])
else:
    st.info("Wgraj plik CSV, aby rozpocząć analizę")

40 linijek. Pełnoprawny dashboard z uploadem, statystykami i wykresem.

Deployment

Najprostsza opcja: Streamlit Community Cloud — free tier, deploy z GitHub jednym kliknięciem.

bash
$pip freeze > requirements.txt
$git init && git add . && git commit -m "init"
$git push origin main

Na share.streamlit.io łączysz konto GitHub, wskazujesz repo i plik app.py. Aplikacja dostaje publiczny URL nazwa.streamlit.app.

Alternatywy: Docker + VPS, Hugging Face Spaces, własny serwer z reverse proxy.

Co warto zapamiętać

  • Streamlit re-runuje skrypt od góry do dołu przy każdej interakcji — to nie bug, to feature
  • @st.cache_data dla danych, @st.cache_resource dla modeli i klientów
  • st.session_state dla rzeczy, które muszą przeżyć re-run
  • Layout (st.columns, st.tabs, st.sidebar) ogarniesz w 5 minut
  • Deployment przez Community Cloud — bezpłatny, idealny do MVP i portfolio

Streamlit nie zastąpi pełnoprawnego frameworka frontendowego do produktu B2C z milionami użytkowników. Ale do narzędzi wewnętrznych, dashboardów, prototypów ML i demo dla klienta — bije konkurencję na głowę pod kątem czasu od pomysłu do działającej aplikacji.