Streamlit Notebook : A reactive notebook interface for Streamlit (upgrades)

Hey!

I’ve been re-working on Streamlit-Notebook quite a lot lately.

It’s a reactive notebook interface 100% compatible with Streamlit, inspired by marimo.io

To try it just do:

pip install streamlit-notebook

then run

st_notebook

to launch the interface.

Or just click here to test the online demo.

I’ve always felt that such a tool was missing in the ecosystem.

The latest improvement was to make the notebook files be plain python scripts (instead of JSON) looking like :

from streamlit_notebook import get_notebook, render_notebook
import streamlit as st

st.set_page_config(page_title="Sales Dashboard", layout="wide")
nb = get_notebook(title='sales_dashboard')

@nb.cell(type='code')
def setup():
    import pandas as pd
    import plotly.express as px

@nb.cell(type='code')
def load_data():
    df = pd.read_csv("sales_data.csv")  # 1M rows, ~10 seconds
    df['date'] = pd.to_datetime(df['date'])
    print(f"Loaded {len(df):,} records")

@nb.cell(type='code', auto_rerun=True)
def filters():
    region = st.multiselect("Regions", df['region'].unique())
    date_range = st.date_input("Date range", [df['date'].min(), df['date'].max()])

@nb.cell(type='code', auto_rerun=True)
def dashboard():
    filtered = df[df['region'].isin(region)] if region else df
    st.metric("Total Sales", f"${filtered['amount'].sum():,.2f}")
    st.plotly_chart(px.line(filtered.groupby('date')['amount'].sum()))

render_notebook()

Such notebook files can be run directly with streamlit run my_notebook.py. This way your notebook files are readable, easy to modify directly and can be deployed as apps on the cloud (app mode).

You’ll find all the information you need on the repo.

Tell me what you think of it!

Cheers!

6 Likes

Hey,

Made a few upgrades and corrected some minor bugs:

  • We can now manually change a cell type (‘python’, ‘markdown’, or ‘html’) after it is created
  • No more bug when inserting a new cell above/below an existing one.
  • Smoother UI behavior for dynamic cell creation / execution
  • Programmatic modification of a cell’s code now automatically reflects in the cell’s editor UI
  • Saved notebooks .py files now have a simpler API using the st_notebook factory and nb.render()method directly, instead of the previous get_notebook and render_notebook helpers (this is a breaking change, you should update your existing notebook files accordingly):
from streamlit_notebook import st_notebook
import streamlit as st

nb = st_notebook(title='my_notebook')

@nb.cell(type='code',reactive=True)
def hello():
    st.write("Hello world!")

nb.render()

Don’t forget to pip install streamlit-notebook –upgrade to get the latest version.

Feel free to give your feedback if you find a bug or to suggest new useful features.

Cheers!

2 Likes

A couple of all-nighters later with my buddy Claude…

The package is now much more well rounded, with added AI agent integration.

I won’t surprise you when I say this was the whole point right from the beginning…

For now its just OpenAI for the sake of simplicity (one OPENAI_API_KEY to rule them all : LLM, TTS, STT, vision, embeddings, even image if we need it, and everybody already has one).
But I will enable switching providers at some point (Anthropic would be only justice, since Claude coded at least 75% of this).

Features :

  • AI chat mode in the sidebar. Chat while you work on the notebook.
  • Agent has complete context visibility over the notebook (including content, states and execution outputs of cells)
  • Agent can run code in the notebook’s shell (Same interactive session as the cells).
  • Agent has complete dynamic control over the notebook and code cells via the shell and the notebook’s programmatic API (can create, edit, run, delete cells, change cell properties, save, open, export notebook, etc.). Basically all the user can do from the interface, it can do as well.
  • Multimodal: Reads many document types (files or urls), reads web pages, inspect python objects, observe images, supports voice interaction (both ways) with text stream synced with voice.
  • Can be accessed programmatically via __agent__ from the namespace (including calling its tools as functions, using result=__agent__.tools.<tool_name>(**kwargs), the agent may thus chain several tool calls programmatically in a single run_code API tool call .
  • Possibility to define and add tools to the agent dynamically from within the session.

+Upgraded the display function to support any streamlit display backend and parameters via:

display(obj,backend='write',**kwargs)
# equivalent to st.<backend>(obj,**kwargs)
# but works in one-shot cells as expected

+Many minor bug fixes and UX improvements.

So basically we have :

  • a User which controls a web UI, which controls a python shell (easy, Jupyter does it all already)
  • a shell that not only can return displays to the UI (classic) but can pop interactive widgets at will and can control the whole UI dynamically using the very language of the UI framework in an interactive setting (this, Jupyter can’t really do! Not even Reflex, or any other! Thank you Streamlit!)
  • One persistent namespace shared by everybody (Agent, UI, Shell, User)
  • namespace/UI reactivity with a synchronous core runtime (except the main Streamlit async loop of course, and stream handlers working with threads).
  • a User which pilots the UI which pilots the Agent (all nice an streamable, with voice + vision) + the shell (with streamed stdout/stderr/display outputs, obviously)
  • an AI agent which controls the shell… and therefore the UI… and therefore the User (haha!)
  • Everybody controls everybody reactively or programmatically at the same level of execution
  • Profit!

All tested working on Streamlit Cloud which alone is pretty good news…

Hope you like it!

This codebase has too little many stars for the absurd amount of unpaid time spent on it, I tell you… Claude doesn’t quite care about the time, but we both did try our best on this one and a couple of stars for us (if deemed well deserved!) would be much appreciated… :sweat_smile:

We want stars!
Give us ALL the stars! :star:

:slightly_smiling_face:

Cheers!

2 Likes

streamlit-notebook v0.3.0 is out.

Features:

  • Improved UI/UX : better cell UI interface, possibility to minimize cells to free up screen space, new Quit button to close the Streamlit server elegantly (having to hit Ctrl+C in the terminal was not ideal…), and other little stuff.
  • Introduced the newlayout parameter in the st_notebook factory. Basically equivalent to st.set_page_config, but letting you choose the initial layout width (in %) of the main display, rather than just ‘centered’ or ‘wide’). I also added a slider in the sidebar to adapt the width live from the interface. Note: You don’t need to call st.set_page_config anymore in your notebook files, and attempting to do so will raise an error.
  • all features now working properly (many bug fixes)
  • better modularity, organization and documentation of the codebase
  • moved the modict utility used throughout the project to a separate package (it’s a powerful dict subclass with dataclass/Pydantic-like features, but much more flexible. Bundled with its own advanced runtime type checker and coercer (thank you Claude! :sweat_smile:). Check it out! : here)

Just pip install streamlit-notebook --upgrade to get the latest version

Hope you like it!

Cheers !

1 Like