👑

Embed Streamlit apps anywhere with PixieBrix (10 min)

🐍

This tutorial assumes you know basic Python for working with Streamlit applications

Streamlit is an awesome tool for turning Python scripts into web apps. Think Jupyter notebooks, but instead of notebooks, you can turn scripts into interactive applications that can be used by anyone on the web!

By combining Streamlit and PixieBrix, you can embed a Python-based web app into any web page, and automatically use context from the page as an input into the app.

In this tutorial, we'll take Max Bolger's NFL Receiver dashboard application and embed it into the CBS Sports Fantasy Football player profile page. We'll adapt the app so it dynamically updates based on which player we're viewing.

image

Create your Streamlit app

Streamlit has some great tutorials to get started. For this tutorial, we'll start with Max Bolger's NFL Receiver dashboard application and adapt it for embedding in the PixieBrix sidebar.

image

To do this I found the project on GitHub, and created my own fork: https://github.com/twschiller/nfl-receiver-dashboard/blob/main/receiver-dashboard.py

Expose inputs via URL Parameters

Streamlit version 0.65.0 released in August 2020, introduced support for passing context to your application using URL query parameters (sometimes called search parameters).

In your Streamlit app, you can access the query parameters via the experimental_get_query_params method. For example, let's say you wanted to read a parameter called text from the URL

# https://github.com/streamlit/release-demos/blob/master/0.65/demos/query_params.py
query_params = st.experimental_get_query_params()
text_input = query_params["text"][0] if "text" in query_params else ""

You can then use that value with the input components on the page:

x = st.text_area('Enter Text', value=text_input)

For adapting the wide receiver dashboard, I exposed a parameter player, that accepts the name of the player. I then default the selected player to that player if it's found:

if default_player:
	default_record_index = next((i for i, x in enumerate(records) if x["full_name"] == default_player), None)
else:
	default_record_index = None

selected_data = st.selectbox(
	'Select a Player',
	options=records,
	index=default_record_index or 0,
	format_func=lambda record: f'{record["full_name"]}'
)

Because we'll be placing the app in the PixieBrix Sidebar, I also chose a couple of the visualizations I found most useful and removed the others. I also changed the layout to use a single column.

Share your Streamlit app

In October 2020, Streamlit introduced support for sharing your Streamlit creations directly from your a GitHub code repository.

Once you share your app, you can access via it's share.streamlit.io URL:

https://share.streamlit.io/twschiller/nfl-receiver-dashboard/main/receiver-dashboard.py

Since we've exposed player parameter, we can access the URL with a player name to see the visualizations directly for that player:

Add a Streamlit App to the PixieBrix Sidebar

🌴

Before you begin this step, make sure you've Installed PixieBrix

Navigate your browser to a CBS Sports Fantasy Football player profile page. Then, open the PixieBrix Page Editor, and grant PixieBrix access to the page.

Add a SideBar

Click Add in the top left of the PixieBrix Page Editor and choose Sidebar Panel, and then + Create New.

We want to make the Sidebar available on every CBS Sports football player profile page, but not unrelated CBS Sports pages (like basketball or hockey). To configure this, go to the Page Editor's Availability tab and change the Match Patterns from https://www.cbssports.com/* to https://www.cbssports.com/fantasy/football/players/*

Get the Player's Name from the Page

We'll use a jQuery selector to get the player's name from the web page.

Go to the Page Editor's Data tab and click Add Property.

First, rename "property1" to "playerName"

Then click the Pointer Icon below Value and hover your mouse over the player's name, "A.J. Brown"

image

From the dropdown, let's select the .player-name selector for the name. This selector will work even if the CBS Fantasy page adds additional headers to the page

image

Passing the Player to Streamlit App

Now that we have a variable with the player name, we'll modify the IFrame URL to use the player name variable.

Go to the Page Editor's Content tab and click + Add Brick.

Search and select the "Construct URL" brick.

image

To construct the URL, we'll paste in the URL of our Streamlit app:

https://share.streamlit.io/twschiller/nfl-receiver-dashboard/main/receiver-dashboard.py

Additionally, we'll add a parameter entry for each entry we want to pass to the application:

image

Attach the IFrame

In the Page Editor Content tab click + Add Brick.

Search and select the "IFrame" brick.

image

The Construct URL brick returns an output with a url property. We can use this url variable as the input to our IFrame brick. Make the Height 100% and Width 100%.

image

Finally click Render Panel and Save.

Test the App

Your PixieBrix Sidebar should now display the adapted NFL Receiver Dashboard. You can test it on another wide receiver page, for example Davante Adams. The app should dynamically update.

image

Conclusion

We're excited about pairing PixieBrix panels with Streamlit apps, and the many possibilities it creates. Here are three ideas we recently heard:

  1. COVID-19 Analytics: the Johns Hopkins COVID-19 Dashboard provides regional Status Reports; you could embed a Streamlit app that updates based on which region you select.
  2. Sales Reporting: You could embed a Streamlit app into your company's CRM to show analytics by customer, product segment, etc.
  3. Movie Recommendations: You could embed a Streamlit app into the IMDb movie pages that shows the output of a movie recommendation engine.