0.89.0 release notes

This release launches configurable hamburger menu options and experimental primitives for caching

Posted in Release Notes, September 22 2021

Hey Streamlit Fam! πŸ‘‹

We're excited to introduce the 0.89.0 release with two notable updates: new configurable hamburger menu options and new experimental primitives for caching.

In this post, we'll describe them in detail and talk about other updates. If you can't wait to try them outβ€”here's a sample app and here are the docs for the menu changes!

✨ New in Streamlit

We worked on improving the in-app menu (or as we like to call it internally, the hamburger menu πŸ”):

  • Make the menu more useful to viewers. The About menu shows information about Streamlit, but viewers want to see information about the app itself!
  • Reduce confusion. Menu items used to change depending on where the app was hosted. Not anymore.
  • Continue to provide developer-oriented options, such as clear cache.

To address the above, we're introducing two updates:

  1. A new API to customize the menu.
  2. A context-aware visual redesign.

Let's jump right in.

st.set_page_config now accepts the menu_options argument to allow you to configure or remove Get help, Report a bug, and About menu items.

Here it is in action:

menu_items = {
	'Get help': YOUR_HELP_URL_STRING,
	'Report a bug': YOUR_BUG_PAGE_URL_STRING,
	'About': '''
	 ## My Custom App
	 Some markdown to show in the About dialog.
	'''
}
st.set_page_config(menu_items=menu_items)

And here is the About menu with Markdown (it's as simple as copying your README.md from the app repo into the tab):

![](upload://joTssXporUMT7BqbljGHAmkUbP1.jpeg)

You can disable menu items by setting None as the menu item's value. For more information, see the documentation for set_page_config .

2. Context-aware visual redesign

The hamburger menu is now divided into the main section (visible to everyone) and the developer section (visible to developers only).

The developer section is context-aware. It appears if the app is running on localhost or if it was deployed in Streamlit Cloud (and if the current user is the app's developer).

Here is what it looks like:

![](upload://eEGpKbpn6bYfOU5QOL0dymlnCtx.png)

That's it for the hamburger menu! πŸ”

Keep reading below for updates on caching and other notes from the 0.89.0 release.

βš™οΈ New experimental primitives for caching

Two years ago, we introduced st.cache as the foundational part of Streamlit's execution model. It lets you write apps linearlyβ€”like a simple script without sacrificing performance.

But this powerful tool came with unexpected complexity (did anyone say hashfuncs 🀯?). st.cache tried to solve too many problems at the same time.

Today we're introducing two experimental primitives that focus on specific use-cases of st.cache: st.experimental_memo and st.experimental_singleton.

We're releasing these features early because we want to get your feedback!

Please give them a try and take it to the forums with bugs, thoughts, and (hopefully) praise. And don't worry. None of this will impact your ability to use the current st.cache. πŸ˜„

Here is how these primitives work:

st.experimental_memo

Use it to store expensive computation which can be "cached" or "memoized" in the traditional sense. It has the same API as the existing st.cache:

@st.experimental_memo
def load_csv(filename):
    df = pd.read_csv(filename)
    return df
df = load_csv('my-data.csv')

It's that simple! See this blog post for more information.

st.experimental_singleton

This is a key-value store that's shared across all Streamlit app sessions. Use it for storing objects that are initialized once but are used multiple times throughout your app (like Tensorflow sessions and database connections):

from sqlalchemy.orm import sessionmaker
@st.singleton
def get_db_sessionmaker():
    # This is for illustration purposes only
    DB_URL = "your-db-url"
    engine = create_engine(DB_URL)
    return sessionmaker(engine)

That's it for st.experimental_memo and st.experimental_singleton! Read this blog post for more details.

We're excited to see what you do with these new primitives. To use them, upgrade Streamlit as usual:

pip install --upgrade streamlit

πŸ‘Ÿ Other notable updates

  • πŸ’… We've updated our UI to a more polished look to improve typography, vertical rhythm, and so much more (including our favorite, the UI for dataframes!)
  • 🎨 We now support theme.base in the theme object when it's sent to custom components. [3737].
  • 🧠 We've modified session state to reset widgets if any of their arguments changed (even if they provide a key). Some widget behavior has changed as result, but these are a minority of cases. Besides, we find this is the best API both in theory and in practice. See docs for more.
  • 🐞 Bug fixes: st.image now supports SVG URLs [#3809] and SVG strings that don't start with an <svg> tag [#3789].

🏁 Wrapping up

Thank you for reading the 0.89.0 release notes. You can always see the most recent updates on our changelog or via this tag on the forum.

Let us know in the comments if you have any questions. We're looking forward to hearing what you think!

Happy Streamlit-ing. 🎈


This is a companion discussion topic for the original entry at https://blog.streamlit.io/0-89-0-release-notes/

Hi, I noticed the update on the UI for dataframes. Is there a way to configure the color scheme of the headers and index? In the past it used to be a grayish color (the same as the sidebar background) and made it very easy to distinguish from the main dataset. Now the background is white and very hard to read. In the theme options doc, it mentions that changing the secondaryBackgroundColor will change the headers of dataframes as well, but doesn’t seem to work in the latest 0.89 release. Thanks in advance!

EDIT: Here’s the theme options doc I was refering to: Theme option reference β€” Streamlit 0.89.0 documentation

Absolutely agree with you, dataframes got that awkward representation style! Any ideas how to fix this? Any custom CSS code so far can not handle it for me.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.