From ML Apps to Sales Dashboards, Streamlit Does it All

At Fenris, we thrive on data. We load, we clean, we analyze, we visualize.

Fortunately, we are able to leverage robust tools that support us in our data-centric processes.

We recently began using a new tool that has the capacity to facilitate all of the above operations with incredible simplicity. Streamlit is an open-source Python library that is fast, free, and easy to use.

Streamlit enables users to construct user friendly data apps in just a few lines of code, exclusively with Python. For the first time, developers don’t have to utilize HTML, CSS, Javascript, etc. to achieve the aesthetic front end that is necessary for effective and classy communication. The Streamlit team has turned the idea of an “easy peasy data app framework” pipe dream into a reality.

Streamlit Features and Functions

Below are some of Streamlit’s most impressive features, and why we here at Fenris value them so much.

Instant Deployment

Streamlit allows for instant app deployment. Once our development team completes an iteration of development on a project, say for example, our internally operated sales demo dashboard, we can instantly push the updates to our live app. This helps to facilitate a fast-paced development-feedback cycle, allowing for constructive iteration between our sales and development teams. See the video below to see just how easy app deployment is with Streamlit sharing.

Sharing data apps with Streamlit just involves access to a code repository and a requires few simple clicks.
Customizable Caching

Streamlit supports complex and customizable caching, thus making apps more efficient. Apps are also faster on reruns. Though we are not yet using the more complex forms of caching that Streamlit supports, we do use the caching systems to store our data (avoiding unnecessary reloads), images, and default values.

Caching in Streamlit occurs with a simple function decorator. In the example below, the function will take 15 seconds to execute and print the desired result when the app is first loaded. However, when the page reloads, the function result caches, and the result appears almost instantaneously to the user.

import streamlit as st
import time

@st.cache
def resource_consuming_func(a, b):
    time.sleep(15)  # This makes the function take 15s to run
    return a + b

result = resource_consuming_func(a=5, b=10)

st.write(f"Result: {result}")
Secrets/Password Management:

Streamlit has a built in secrets management framework, which facilitates the storage of protected values. These values are treated like environment variables in the Python scripts. This keeps confidential information safe from malicious or unqualified users. The Streamlit sharing platform seamlessly integrates secrets management.

We use this feature primarily for API access credential storage.

A streamlit sharing secrets management tab.
The secret management dialog for the Streamlit sharing platform.
Tabular and Graphical Data Visualization

Data visualization is Streamlit’s specialty. The library’s emphasis on scripting makes sharing data figures easy and intuitive, and the focus on interactivity makes interpretation of such figures painless. Matplotlib, altair, vega lite, plotly, bokeh. You name it — and Streamlit probably has integration for it. Charts, graphs, and tables are all highly palatable. The dataframe below, for example, is displayed with Streamlit’s standard theming and color scheme.

A streamlit dataframe display.
Interactivity and Forms

Nowhere is Streamlit’s spotlight on interaction more evident than the newly released Streamlit forms. We have found these forms quite helpful in facilitating data pulls from our APIs with the Streamlit structure as our GUI. As with other Streamlit widgets, creating a form is fast and simple.

Additionally, by treating the widgets as variables, their values can be referenced easily in following code/operations.

# Forms can be declared using the 'with' context manager syntax
with st.form(key='my_form'):
    text_input = st.text_input(label='Enter your name')
    fav_number_input = st.slider(label='Enter your favorite number', min_value=0, max_value=100)
    birthday_input = st.date_input(label='Enter your birthday')
    submit_button = st.form_submit_button(label='Submit')
A Streamlit input form with space for text name input, slider numerical input, and calendar date input. The image uses Streamlit standard theming.
Custom Theming

Streamlit has functionality for customizing the color scheme and font patterns. This is useful from an industry sales standpoint, as apps can now adopt a company color palette and font scheme. In our case, we have utilized this feature to customize our internal sales demo app.

Our Life Events monitor sales demo page utilizes many of Streamlit’s widget features, such as tables, dropdown selection menus, text boxes, and the sidebar. The font, background, and widget colors have been customized to model our company aesthetics.

Streamlit has become a useful tool for us here at Fenris. We use the data app framework for exploratory projects, automating our data pulls, and demoing our services to potential and current customers.

What to Avoid with Streamlit

All of Streamlit’s wonderful features aside, we’ve made some mistakes along the way. Here’s how you can avoid our missteps.

  • Be careful with pagination. Streamlit has recently implemented pagination capability for DataFrames, but there is not yet a full proof method for changing between main pages/screens. Streamlit allows for navigation with radio controls on the sidebar, but this can become messy within your code. It’s not to say that pagination isn’t possible, but consider first how you might be able to simplify your app before you try to build a large network of pages for your work.
    • Additionally, Streamlit’s recent installation of session state introduces many new possibilities for simplifying pagination/changing in-between displays. We at Fenris are looking forward to exploring this new feature.
  • Take advantage of Streamlit’s built in formatting. Streamlit has built in support for columnar layout, expanding tabs, sidebar navigation, and a wonderful set of diverse widgets. If you attempt to stray too far from the Streamlit formatting by implementing your own style with CSS and HTML injection, your code will quickly bulk up in complexity, and you likely won’t see results that are significantly different than what you began with.
    • Still, we did use some HTML injection for small customizations. For example, to center the text above these photos, we had to utilize the aforementioned strategy.
    • In other words, keep it simple. The Streamlit interface is already sleek. You won’t be dissapointed.
streamlit_cols[col_num].markdown(
     f"<h4 style='text-align: center; color: #0C2E4F; family:Roboto;'>{label_text}</h4>",
     unsafe_allow_html=True,
)
A Streamlit display of 3 policyholders and their respective addresses in a columnar format.

What’s next?

What’s next for our team with this tool? Well, there’s a lot.

We are quite excited to explore the new “Streamlit for teams” functionality. Similar to the sharing service, the teams service assists in instant app deployment, with the added protection of authentication services for users and developers.

Additionally, we are looking forward to using the library’s new session state feature. This addition introduces the ability to store information across app interactions and reruns.

We have just barely scratched the surface of all that Streamlit has to offer with regards to the integration of data science and machine learning techniques within our Streamlit data apps.

If you’re intrigued, confused, or simply curious, find more information about Streamlit here.

Posted in