Version 1.28.0


  • :test_tube: Introducing a new testing framework for Streamlit apps! Check out our documentation to learn how to build automated tests for your apps.
  • :computer: Announcing the general availability of st.connection, a command to conveniently manage connections in Streamlit apps. Check out the docs to learn more.
  • :snowflake: SnowparkConnection has been upgraded to the new and improved SnowflakeConnection β€” the same, great functionality plus more! Check out our built-in connections.
  • :hammer_and_wrench: st.dataframe and st.data_editor have a new toolbar! Users can search and download data in addition to enjoying improved UI for row additions and deletions. See our updated guide on Dataframes.

Notable Changes

  • :cyclone: When using a spinner with cached functions, the spinner will be overlaid instead of pushing content down (#7488).
  • :date: st.data_editor now supports datetime index editing (#7483).
  • :1234: Improved support for decimal.Decimal in st.dataframe and st.data_editor (#7475).
  • :disguised_face: Global kwargs were added for hashlib (#7527, #7526). Thanks, DueViktor!
  • :clipboard: st.components.v1.iframe now permits writing to clipboard (#7487). Thanks, dilipthakkar!
  • :memo: SafeSessionState disconnect was replaced with script runner yield points for improved efficiency and clarity (#7373).
  • :robot: The Langchain callback handler will show the full input string inside the body of a st.status when the input string is too long to show as a label (#7478). Thanks, pokidyshev!
  • :chart_with_upwards_trend: st.graphviz_chart now supports using different Graphviz layout engines (#7505, #4089).
  • :butterfly: Assorted visual tweaks (#7486, #7592).
  • :bar_chart: plotly.js was upgraded to version 2.26.1 (#7449, #7476, #7045).
  • :minidisc: Legacy serialization for DataFrames was removed. All DataFrames will be serialized by Apache Arrow (#7429).
  • :framed_picture: Compatibility for Pillow 10.x was added (#7442).
  • :mailbox_with_mail: Migrated _stcore/allowed-message-origins endpoint to _stcore/host-config (#7342).
  • :speech_balloon: Added post_parent_message platform command to send custom messages from a Streamlit app to its parent window (#7522).

Other Changes

  • :keyboard: Improved string dtype handling for DataFrames (#7479).
  • :black_nib: st.write will avoid using unsafe_allow_html=True if possible (#7432).
  • :bug: Bug fix: Implementation of st.expander was simplified for improved behavior and consistency (#7247, #2839, #4111, #4651, #5604).
  • :beetle: Bug fix: Multipage links in the sidebar are now aligned with other sidebar elements (#7531).
  • :ant: Bug fix: st.chat_input won’t incorrectly prompt for label parameter in IDEs (#7560).
  • :honeybee: Bug fix: Scroll bars correctly overlay st.dataframe and st.data_editor without adding empty space (#7090, #6888).
  • :lady_beetle: Bug fix: st.chat_message behaves correctly with the removal of AutoSizer (#7504, #7473).
  • :spider: Bug fix: Anchor links are reliably produced for non-English headers (#7454, #5291).
  • :snowman_with_snow: Bug fix: st.connections.SnowparkConnection more accurately detects when it’s running within Streamlit in Snowflake (#7502).
  • :cockroach: Bug fix: A user-friendly warning is shown when exceeding the size limitations of a pandas Styler object (#7497, #5953).
  • :fly: Bug fix: st.data_editor automatically converts non-string column names to strings (#7485, #6950).
  • :microbe: Bug fix: st.data_editor correctly identifies non-range indices as a required column (#7481, #6995).
  • :mosquito: Bug fix: st.file_uploader displays compound file extensions like csv.gz correctly (#7362). Thanks, mo42!
  • :scorpion: Bug fix: Column Configuration no longer uses deprecated type checks (#7496, #7477, #7550). Thanks, c-bik!
  • :cricket: Bug fix: Additional toolbar items no longer stack vertically (#7470, #7471).
  • :spider_web: Bug fix: Column Configuration no longer causes a type warning in Mypy (#7457). Thanks, kopp!
  • :snail: Bug fix: Bokeh Sliders no longer cause JavaScript errors (#7441, #7171).
  • :lizard: Bug fix: Caching now recognizes DataFrames with the same values but different column names as different (#7331, #7086).

Can’t wait to try the new testing framework :test_tube:

Awesome work!! :balloon:


I am struggling with it.

How can I simulate a tab selection?

In the to be tested Python file:

tab1, tab2, tab3 = st.tabs(["Hitchhiking", "Driving", "Booking"])

The testing:

# Choose tab `Driving`
# or

isn’t working. is it possible to simulate a tab selection through the testing API?

What would be the point? Selecting a tab has no detectable effect on the application so there is nothing to test there,

Yes, I just learned I can test input elements in the different tabs (no tab change needed).


Published a walkthrough of the testing framework here:

Also has links in the description to a couple of app repos with example tests to help you get started :slight_smile: Let us know how it is!


I made an Streamlit AI assistant named, Streamly. The initial idea was to show me all the features of 1.28. So the core logic integrates 1.28, and @mathcatsand notes. :wink: I hope it helps others like it helped me visually see the changes on the fly.

1 Like

New download option for csv is buggy, freezes browser. This is way faster:

if not data.empty:
            csv = data.to_csv(index=False).encode('utf-8')
            if st.download_button(
                label="Download CSV",
                st.write('Download Completed!')