How I Used Streamlit and Heroku to Create a Live Demo for My Python Library

José Fernando Costa
Sep 3 · 7 min read

Recently I came across Streamlit and I’m enjoying my time developing with it. As described in the documentation,

Streamlit’s open-source app framework is the easiest way for data scientists and machine learning engineers to create beautiful, performant apps in only a few hours

And it’s true. The API is easy to learn but powerful. For instance, to create a basic web app that receives some text input and writes it back to the page

Basic Streamlit web app
Basic Streamlit web app
Basic Streamlit web app

You only need three lines of Python code

import streamlit as st
my_text_input = st.text_input("Type to your heart's content", "Hello World")
st.write(f"You entered: {my_text_input}")

st.text_input creates a text input field. The first argument is the label displayed above the field, and the second argument is the default/placeholder value. This function returns the value entered in the field as a string, which is saved as the my_text_input variable. In the next line, st.write simply writes the string to the page. At the end, enter the streamlit run your_script.py in the command line to open the app in your browser.

Oh, and in case you’re wondering, those three lines of code also cover handling state:

Streamlit detects changes in the input fields
Streamlit detects changes in the input fields
Streamlit detects changes in the input fields

Now that you’re acquainted with Streamlit, let me introduce you quotespy before we dive into the Streamlit live demo.

What is quotespy?

quotespy is a Python library to create quotes/lyrics and tweet graphics with PIL. For a while, I reused a Python script to create lyrics graphics and tweet graphics here and there. However, earlier this year I decided to create a proper library so other people could use it too.

I won’t go into detail about quotespy because I wrote an article about it here and the repository’s README covers the features added over time but, in essence, it has two modules: graphics and tweet_graphics. The former lets you create “free-form” graphics with centered text, while the latter is used to create tweet screenshots, including user name, user handle, the tweet and, optionally, a profile picture.

This is a sample graphic result:

quotespy graphic result
quotespy graphic result
quotespy graphic result

And this is a sampletweet_graphics result:

quotespy tweet_graphics result
quotespy tweet_graphics result
quotespy tweet_graphics result

And, of course, the library accepts various graphical settings such as color scheme, dimensions, font, etc. to create these graphics.

quotespy-streamlit: The live demo

When I found Streamlit I knew it would be a great solution to create a live demo for quotespy because a) it would be good practice to learn more about Streamlit and b) it would be easy to create the demo.

quotespy-streamlit demo
quotespy-streamlit demo
quotespy-streamlit demo

The demo is quite simple but it lets users adjust all the quotespy parameters and create their own graphics using both modules of quotespy. As you can see in the GIF above, it starts with some introductory text, followed by a bunch of input fields for each parameter and, at the end, there’s the resulting graphic. Depending on the module chosen in the first input field, the parameters will change. At the very end there’s a download link to export the graphic.

Finally, now that you’ve been introduced to the complete project, let me tell you about how I realized this project at a technical level.

As you can find in quotespy-streamlit’s GitHub repository, I used two python scripts to create the web app: main.py and utils.py. main.py has all the logic for the web app’s structure, that is, what to render, in which order, etc. utils.py has only helper functions to help main.py look cleaner and shorter.

For instance, to render the graphic settings of each quotespy module, main.py simply calls the respective function in utils.py which renders each input field and returns a dictionary with the values entered by the user. Then main.py takes this data and creates the graphic with quotespy.

The hardest parts I had to deal with as someone starting out with Streamlit were creating an RGBA color for the background color (the Streamlit color picker only has RGB, Hexadecimal and HSL options) and creating the download link for the image.

Well, the RGBA color was not hard, it just had to be implemented with a workaround. I used a the color picker to get the color and a slider to choose the transparency. Then I converted the color to RGB and added the transparency as a fourth value (see the hex_to_rgba function in utils.py).

On the other hand, setting up a download link so users could download their image gave me some trouble. I couldn’t just create an anchor element and reference the image, instead I had to create a workaround. After looking in Streamlit’s forums, I found a solution: after saving the created graphic locally, I could load it in bytes mode and convert it to a base 64 bytes object. This way, the anchor element’s could use a data URL. In practice, this means that when the user clicks the link at the end of the page it downloads the image as intended.

Deploying to Heroku

With the app created, I was almost ready to deploy it to Heroku. I found a tutorial for this on YouTube, by Data Professor. He has a playlist of Streamlit tutorials which I recommend if you want to learn more about Streamlit and a bit of Machine Learning.

So, I was missing some extra files which are required to deploy on Heroku:

(for the content of these files please refer to my repository)

With all these files uploaded to the project’s repository, I was finally ready to deploy on Heroku. To create a new Heroku app, connect it to your repository, and deploy, follow these steps (assuming you already have an Heroku account):

Create a new Heroku app

Choose “Create new app”

Create a new Heroku app
Create a new Heroku app
Create a new Heroku app

Give it a valid name, choose a region and create the app

Create the new app
Create the new app
Create the new app

Choose GitHub as the deployment method

Heroku will ask for your permission to connect to your GitHub account if you have not done it before.

Choose GitHub as the deployment method
Choose GitHub as the deployment method
Choose GitHub as the deployment method

Choose a GitHub repository to connect to

Image for post
Image for post

Deploy your repository branch

With automatic deploys enabled, the selected branch will be automatically deployed every time you push new code to the branch. Manual deploys gives you control over when to deploy the application.

Image for post
Image for post

When the deployment ends, you can go to your website using the link at the end of the build logs or click the “Open app” button in the top right corner.

Heroku build logs
Heroku build logs
Heroku build logs

The last hurdle I had in this project was loading the fonts with the app deployed in Heroku. At first I put the fonts in their own folder because, you know, it looks bad to have everything there in the root folder. The problem is that Heroku was not able to detect the files in that folder. Instead, after searching for a while on Google and coming across some solutions for Django applications, my solution was to create a folder called “static”. Now, all static files that I have (in my case fonts, but it could be any other files) are stored inside this folder. The final project structure was this:

Project structure
Project structure
Project structure

Conclusion

This project was fun and a valuable learning experience. I liked working with Streamlit, as it made creating this web app extremely easy and it allowed me to create an interactive demo for quotespy that is always available online. Of course, this would not have been possible without Heroku. I had not used Heroku before this project, but I’m satisfied with it. Aside from that “static” folder problem which was clearly due to my lack of knowledge of the platform, it was a painless experience deploying my code from GitHub.

Overall, I’m extremely happy with the project and its results 😁

And before you go, here are the most important links I mentioned throughout the article:

Please let me know if you have any questions and/or feedback :)

The Startup

Medium's largest active publication, followed by +733K people. Follow to join our community.

José Fernando Costa

Written by

I write technical articles about data analysis and other things that catch my attention

The Startup

Medium's largest active publication, followed by +733K people. Follow to join our community.

José Fernando Costa

Written by

I write technical articles about data analysis and other things that catch my attention

The Startup

Medium's largest active publication, followed by +733K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store