Dynamically adding rows in Streamlit vs Panel

After trying out Streamlit, I truly appreciate how Panel makes session state management simple! There’s no need to manually keep track of your widgets in Panel!

ezgif.com-video-to-gif (6)
ezgif.com-video-to-gif (5)

Streamlit:

import random
from uuid import uuid4

import streamlit as st


def create_row(hex_id=None):
    """
    Dynamically add a new row to the app.
    """
    value = random.randint(0, 100)
    if hex_id is None:
        hex_id = uuid4().hex
        st.session_state.rows[hex_id] = value
    else:
        value = st.session_state.rows[hex_id]

    st.number_input("Enter a number", value=value, key=f"num_{hex_id}")


# Initialize rows if it doesn't exist in session_state
st.session_state.setdefault("rows", {})

main = st.columns(1)
with main[0]:
    # Layout objects
    st.title("Dynamically add new rows")

    button_cols = st.columns(2)
    with button_cols[0]:
        add_row = st.button("Add new row", use_container_width=True)
    with button_cols[1]:
        clear_rows = st.button("Clear all rows", use_container_width=True)

    # Add interactivity
    if clear_rows:
        st.session_state.rows = {}

    for hex_id in st.session_state.rows.keys():
        create_row(hex_id=hex_id)

    if add_row:
        create_row()

Panel:

import random

import panel as pn
pn.extension(sizing_mode="stretch_width")


def create_row(hex_id=None):
    """
    Dynamically add a new row to the app.
    """
    value = random.randint(0, 100)
    row = pn.widgets.TextInput(name="Enter a number", value=str(value))
    rows.append(row)

# Layout objects
rows = pn.Column()
add_row = pn.widgets.Button(name="Add new row")

clear_rows = pn.widgets.Button(name="Clear all rows")
button_cols = pn.Row(add_row, clear_rows)
main = pn.Column("# Dynamically add new rows", button_cols, rows)

# Add interactivity
clear_rows.on_click(lambda _: rows.clear())
add_row.on_click(lambda _: create_row())

pn.template.BootstrapTemplate(main=[main], main_max_width="max(50%, 600px)").servable()
2 Likes