├── .devcontainer └── devcontainer.json ├── .streamlit └── config.toml ├── 3AF34648-C61D-47CE-9E56-C496C5A7C240.jpeg ├── LICENSE ├── README.md ├── content ├── Day1.md ├── Day10.md ├── Day11.md ├── Day12.md ├── Day13.md ├── Day14.md ├── Day15.md ├── Day16.md ├── Day17.md ├── Day18.md ├── Day19.md ├── Day2.md ├── Day20.md ├── Day21.md ├── Day22.md ├── Day23.md ├── Day24.md ├── Day25.md ├── Day26.md ├── Day27.md ├── Day28.md ├── Day29.md ├── Day3.md ├── Day30.md ├── Day4.md ├── Day5.md ├── Day6.md ├── Day7.md ├── Day8.md ├── Day9.md ├── figures │ ├── Day1.csv │ ├── Day20.csv │ └── Day6.csv └── images │ ├── 0CEEBB8C-29FB-4B85-9932-CEF642777A8A.jpeg │ ├── 2C9104F7-CF84-4DAF-9004-52BB4644CF28.png │ ├── 77EC58A5-25FD-4477-A74E-421333312514.jpeg │ ├── 7A7B0072-71ED-42BD-B985-B0D35CF03A1F.jpeg │ ├── 8032B4CC-A9BD-4B4F-8DFB-EBE7326886DE.jpeg │ ├── 8085E82C-304F-48EE-8AD6-3F941E31860B.jpeg │ ├── 8ED4483A-58C6-4F76-BE59-C8CC6DCDB95E.jpeg │ ├── F8DCC7EB-D497-426D-904F-6941E2C4B750.jpeg │ └── readme.md ├── requirements.txt ├── streamlit-logo-secondary-colormark-darktext.png └── streamlit_app.py /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Python 3", 3 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 4 | "image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye", 5 | "customizations": { 6 | "codespaces": { 7 | "openFiles": [ 8 | "README.md", 9 | "streamlit_app.py" 10 | ] 11 | }, 12 | "vscode": { 13 | "settings": {}, 14 | "extensions": [ 15 | "ms-python.python", 16 | "ms-python.vscode-pylance" 17 | ] 18 | } 19 | }, 20 | "updateContentCommand": "[ -f packages.txt ] && sudo apt update && sudo apt upgrade -y && sudo xargs apt install -y 4 | 5 | This is the official repo of `#30DaysOfStreamlit` — a 30-day social challenge for you to learn, build and deploy [Streamlit](https://streamlit.io) apps. 6 | 7 | ## How to participate 8 | 9 | All you need to participate is a computer, a basic understanding of Python, and your curiosity. 🧠 10 | 11 | A new challenge is released daily via Streamlit's [Twitter](https://twitter.com/streamlit) and [LinkedIn](https://www.linkedin.com/company/streamlit/posts/?feedView=all) accounts as well as the [`#30DaysOfStreamlit` app](https://share.streamlit.io/streamlit/30days/). 12 | 13 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/streamlit/30days/) 14 | 15 | Complete the daily challenges, share your solutions with us on Twitter or LinkedIn, and get rewarded with cool Streamlit swag! 😎 16 | 17 | ## What are the daily challenges? 18 | 19 | Find out more about the specific challenges by participating! The 30-day challenges are divided by 3 levels of difficulty to appeal to participants of all skill levels: 20 | 21 | | Beginner (Days 1-7) | Intermediate (Days 8-23) | Advanced (Days 24-30) | 22 | | :--- | :---- | :--- | 23 | | Set up your local and cloud coding environments, install Streamlit, and build your first Streamlit app.| Learn about a new [Streamlit command](https://docs.streamlit.io/library/api-reference) each day and use it to create and deploy a simple Streamlit app. | Learn about important topics such as session state, efficient data and memory management via caching, complex layouts, and much more. 24 | 25 | ## Prizes 26 | 27 | If getting up to speed with the fastest and easiest way to build data apps isn't already the best summer gift, you can also win Streamlit goodies! 28 | 29 | Complete the daily challenges, share your solutions with us on [Twitter](https://twitter.com/streamlit) or [LinkedIn](https://www.linkedin.com/company/streamlit/posts/?feedView=all), and get rewarded with cool Streamlit swag! 🎁 30 | 31 | ## Resources 32 | 33 | - The official [`#30DaysOfStreamlit` app](https://share.streamlit.io/streamlit/30days/) where daily challenges are posted 34 | - Our [Twitter](https://twitter.com/streamlit) and [LinkedIn](https://www.linkedin.com/company/streamlit/posts/?feedView=all) feeds for daily updates 35 | - Streamlit [documentation](https://docs.streamlit.io/) and [cheat sheet](https://docs.streamlit.io/library/cheatsheet) for a thorough reference of Streamlit commands 36 | - Our awesome [Gallery](https://streamlit.io/gallery) for inspiration, templates, and community apps 37 | - Our [blog](https://blog.streamlit.io/how-to-master-streamlit-for-data-science/) for tips and the latest Streamlit info 38 | 39 | ## Translations 40 | 41 | Want to help us expand the reach of `#30DaysOfStreamlit` and English isn't your primary language? Translate the challenges into your preferred language and link to them below! 42 | 43 | - [English](https://github.com/streamlit/30days) (Official): [![30 Days of Streamlit](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://30days.streamlit.app) 44 | - [Bengali](https://github.com/jojo96/30days-Bengali) (by [Ujjayanta Bhaumik](https://github.com/jojo96)): [![৩০ দিনে স্ট্রিমলিট্ ](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://30days-in-bengali.streamlit.app/) 45 | - [Chinese](https://github.com/TeddyHuang-00/30days-Chinese) (by [Nan Huang](https://github.com/TeddyHuang-00)): [![30 天学 Streamlit](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://30days-chinese.streamlit.app) 46 | - [Español](https://github.com/streamlit/30days-spanish/) (by [Emiliano Rosso](https://github.com/arraydude)): [![30 Dias de Streamlit](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://30days-in-spanish.streamlit.app/) 47 | - [French](https://github.com/streamlit/30days-French) (by [Charly Wargnier](https://github.com/charlyWargnier/)): [![30 Days of Streamlit en Français!](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://30days-in-french.streamlit.app/) 48 | - [Hindi](https://github.com/streamlit/30days-Hindi): [![Streamlit के 30 दिन](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://30days-in-hindi.streamlit.app/) 49 | - [Polish](https://github.com/streamlit/30days-polish) (by [Michał Nowotka](https://github.com/sfc-gh-mnowotka)): [![Streamlit w 30 dni po Polsku](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://w30dni.streamlit.app/) 50 | - [Portuguese](https://github.com/franciscoed/30days) (by [Francisco Edilton](https://github.com/franciscoed)): [![30 Dias de Streamlit](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://30dias.streamlit.app/) 51 | - [Russian](https://github.com/kseniaanske/30days) (by [Ksenia Anske](https://github.com/kseniaanske)): [![30 Дней Streamlit](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://30days-in-russian.streamlit.app/) 52 | -------------------------------------------------------------------------------- /content/Day1.md: -------------------------------------------------------------------------------- 1 | # Setting up a local development environment 2 | 3 | Before we can actually start building Streamlit apps, we will first have to setup a development environment. 4 | 5 | Let's start by installing and setting up a conda environment. 6 | 7 | ## **Install conda** 8 | - Install `conda` by going to https://docs.conda.io/en/latest/miniconda.html and choose your operating system (Windows, Mac or Linux). 9 | - Download and run the installer to install `conda`. 10 | 11 | ## **Create a new conda environment** 12 | Now that you have conda installed, let's create a conda environment for managing all the Python library dependencies. 13 | 14 | To create a new environment with Python 3.9, enter the following: 15 | ```bash 16 | conda create -n stenv python=3.9 17 | ``` 18 | 19 | where `create -n stenv` will create a conda environment named `stenv` and `python=3.9` will setup the conda environment with Python version 3.9. 20 | 21 | ## **Activate the conda environment** 22 | 23 | To use a conda environment that we had just created that is named `stenv`, enter the following into the command line: 24 | 25 | ```bash 26 | conda activate stenv 27 | ``` 28 | 29 | ## **Install the Streamlit library** 30 | 31 | It's now time to install the `streamlit` library: 32 | ```bash 33 | pip install streamlit 34 | ``` 35 | 36 | ## **Launching the Streamlit demo app** 37 | To launch the Streamlit demo app (Figure 1) type: 38 | ```bash 39 | streamlit hello 40 | ``` 41 | -------------------------------------------------------------------------------- /content/Day10.md: -------------------------------------------------------------------------------- 1 | # st.selectbox 2 | 3 | `st.selectbox` allows the display of a select widget. 4 | 5 | ## What we're building? 6 | 7 | A simple app that asks the user what their favorite color is. 8 | 9 | Flow of the app: 10 | 1. User selects a color 11 | 2. App prints out the selected color 12 | 13 | ## Demo app 14 | The deployed Streamlit app should look something like the one shown in the below link: 15 | 16 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.selectbox/) 17 | 18 | ## Code 19 | Here's the code to implement the above mentioned app: 20 | ```python 21 | import streamlit as st 22 | 23 | st.header('st.selectbox') 24 | 25 | option = st.selectbox( 26 | 'What is your favorite color?', 27 | ('Blue', 'Red', 'Green')) 28 | 29 | st.write('Your favorite color is ', option) 30 | ``` 31 | 32 | ## Line-by-line explanation 33 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 34 | ```python 35 | import streamlit as st 36 | ``` 37 | 38 | This is followed by creating a header text for the app: 39 | ```python 40 | st.header('st.selectbox') 41 | ``` 42 | 43 | Next, we will create a variable called `option` that will accept user input in the form of a **select** input widget via the `st.selectbox()` command. 44 | 45 | ```python 46 | option = st.selectbox( 47 | 'What is your favorite color?', 48 | ('Blue', 'Red', 'Green')) 49 | ``` 50 | As we can see from the above code box, the `st.selectbox()` command accepts 2 input arguments: 51 | 1. The text that goes above the select widget, i.e. `'What is your favorite color?'` 52 | 2. The possible values to select from `('Blue', 'Red', 'Green')` 53 | 54 | Finally, we'll print out the selected color as follows: 55 | ```python 56 | st.write('Your favorite color is ', option) 57 | ``` 58 | 59 | ## Next steps 60 | Now that you have created the Streamlit app locally, it's time to deploy it to [Streamlit Community Cloud](https://streamlit.io/cloud). 61 | 62 | ## References 63 | More about [`st.selectbox`](https://docs.streamlit.io/library/api-reference/widgets/st.selectbox) 64 | -------------------------------------------------------------------------------- /content/Day11.md: -------------------------------------------------------------------------------- 1 | # st.multiselect 2 | 3 | `st.multiselect` displays a multiselect widget. 4 | 5 | ## Demo app 6 | 7 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.multiselect/) 8 | 9 | ## Code 10 | Here's how to use `st.multiselect`: 11 | ```python 12 | import streamlit as st 13 | 14 | st.header('st.multiselect') 15 | 16 | options = st.multiselect( 17 | 'What are your favorite colors', 18 | ['Green', 'Yellow', 'Red', 'Blue'], 19 | ['Yellow', 'Red']) 20 | 21 | st.write('You selected:', options) 22 | ``` 23 | 24 | ## Line-by-line explanation 25 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 26 | ```python 27 | import streamlit as st 28 | ``` 29 | 30 | This is followed by creating a header text for the app: 31 | ```python 32 | st.header('st.multiselect') 33 | ``` 34 | 35 | Next, we're going to use the `st.multiselect` widget to accept input where users will be able to select one or more colors of there choice. 36 | 37 | ```python 38 | options = st.multiselect( 39 | 'What are your favorite colors', 40 | ['Green', 'Yellow', 'Red', 'Blue'], 41 | ['Yellow', 'Red']) 42 | ``` 43 | 44 | Finally, we'll write out the selected colors: 45 | ```python 46 | st.write('You selected:', options) 47 | ``` 48 | 49 | ## Further reading 50 | - [`st.multiselect`](https://docs.streamlit.io/library/api-reference/widgets/st.multiselect) 51 | -------------------------------------------------------------------------------- /content/Day12.md: -------------------------------------------------------------------------------- 1 | # st.checkbox 2 | 3 | `st.checkbox` displays a checkbox widget. 4 | 5 | ## Demo app 6 | 7 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.checkbox/) 8 | 9 | ## Code 10 | Here's how to use `st.checkbox`: 11 | ```python 12 | import streamlit as st 13 | 14 | st.header('st.checkbox') 15 | 16 | st.write ('What would you like to order?') 17 | 18 | icecream = st.checkbox('Ice cream') 19 | coffee = st.checkbox('Coffee') 20 | cola = st.checkbox('Cola') 21 | 22 | if icecream: 23 | st.write("Great! Here's some more 🍦") 24 | 25 | if coffee: 26 | st.write("Okay, here's some coffee ☕") 27 | 28 | if cola: 29 | st.write("Here you go 🥤") 30 | ``` 31 | 32 | ## Line-by-line explanation 33 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 34 | ```python 35 | import streamlit as st 36 | ``` 37 | 38 | This is followed by creating a header text for the app: 39 | ```python 40 | st.header('st.checkbox') 41 | ``` 42 | 43 | Next, we're going to ask a question via `st.write': 44 | ```python 45 | st.write ('What would you like to order?') 46 | ``` 47 | 48 | We're then going to provide some menu items to tick on: 49 | ```python 50 | icecream = st.checkbox('Ice cream') 51 | coffee = st.checkbox('Coffee') 52 | cola = st.checkbox('Cola') 53 | ``` 54 | 55 | Finally, we're going to print custom text depending on which checkbox was ticked on: 56 | ```python 57 | if icecream: 58 | st.write("Great! Here's some more 🍦") 59 | 60 | if coffee: 61 | st.write("Okay, here's some coffee ☕") 62 | 63 | if cola: 64 | st.write("Here you go 🥤") 65 | ``` 66 | 67 | ## Further reading 68 | - [`st.checkbox`](https://docs.streamlit.io/library/api-reference/widgets/st.checkbox) 69 | -------------------------------------------------------------------------------- /content/Day13.md: -------------------------------------------------------------------------------- 1 | # Spin up a cloud development environment 2 | 3 | ### GitPod 4 | To spin up a development environment on the cloud, we can use [GitPod](https://www.gitpod.io/) and this can be done simply by clicking on the following link: 5 | - Try it 👉 https://gitpod.io/#/https://github.com/dataprofessor/streamlit101/ 6 | 7 | As you can see from the URL above, a GitHub repo URL is appended after `https://gitpod.io/#/` which essentially allow GitPod to spin up a development environment using instructions contained within the GitHub repo URL (namely in the `requirements.txt` file that specifically lists the Python libraries to install). 8 | 9 | > Note: There are other similar cloud development environment such as: 10 | > - [GitHub Codespaces](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/setting-up-your-python-project-for-codespaces) 11 | > - [Replit](https://replit.com/) 12 | > - [Cloud9](https://aws.amazon.com/cloud9/) 13 | -------------------------------------------------------------------------------- /content/Day14.md: -------------------------------------------------------------------------------- 1 | # Streamlit Components 2 | 3 | Components are third-party Python modules that extend what's possible with Streamlit [[1](https://docs.streamlit.io/library/components)]. 4 | 5 | ## What Streamlit components are available? 6 | 7 | There are several dozens of Streamlit components featured on Streamlit's website [[2](https://streamlit.io/components)]. 8 | 9 | Fanilo (a Streamlit Creator) curated an amazing list of Streamlit components on a wiki post [[3](https://discuss.streamlit.io/t/streamlit-components-community-tracker/4634)] that lists about 85 Streamlit components as of April 2022. 10 | 11 | ## How to use? 12 | 13 | Streamlit components are just a pip-install away. 14 | 15 | In this tutorial, let's get you started in using the `streamlit_pandas_profiling` component [[4](https://share.streamlit.io/okld/streamlit-gallery/main?p=pandas-profiling)]. 16 | 17 | #### Install the component 18 | 19 | ```bash 20 | pip install streamlit_pandas_profiling 21 | ``` 22 | 23 | ## Demo app 24 | 25 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/streamlit-components/) 26 | 27 | ## Code 28 | Here's how to build a Streamlit app using a component: 29 | ```python 30 | import streamlit as st 31 | import pandas as pd 32 | import ydata_profiling 33 | from streamlit_pandas_profiling import st_profile_report 34 | 35 | st.header('`streamlit_pandas_profiling`') 36 | 37 | df = pd.read_csv('https://raw.githubusercontent.com/dataprofessor/data/master/penguins_cleaned.csv') 38 | 39 | pr = df.profile_report() 40 | st_profile_report(pr) 41 | ``` 42 | 43 | ## Line-by-line explanation 44 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` as well as other libraries used in the app like so: 45 | ```python 46 | import streamlit as st 47 | import pandas as pd 48 | import ydata_profiling 49 | from streamlit_pandas_profiling import st_profile_report 50 | ``` 51 | 52 | This is followed by creating a header text for the app: 53 | ```python 54 | st.header('`streamlit_pandas_profiling`') 55 | ``` 56 | 57 | Next, we load in the Penguins dataset using the `read_csv` command of `pandas`. 58 | ```python 59 | df = pd.read_csv('https://raw.githubusercontent.com/dataprofessor/data/master/penguins_cleaned.csv') 60 | ``` 61 | 62 | Finally, the pandas profiling report is generated via the `profile_report()` command and displayed using `st_profile_report`: 63 | ```python 64 | pr = df.profile_report() 65 | st_profile_report(pr) 66 | ``` 67 | 68 | ## Making your own Components 69 | 70 | If you're interested in making your own component, please check out the following resources: 71 | - [Create a Component](https://docs.streamlit.io/library/components/create) 72 | - [Publish a Component](https://docs.streamlit.io/library/components/publish) 73 | - [Components API](https://docs.streamlit.io/library/components/components-api) 74 | - [Blog post on Components](https://blog.streamlit.io/introducing-streamlit-components/) 75 | 76 | Alternatively, if you prefer to learn using videos, our engineer Tim Conkling has put together some amazing tutorials: 77 | - [How to build a Streamlit component | Part 1: Setup and Architecture](https://youtu.be/BuD3gILJW-Q) 78 | - [How to build a Streamlit component | Part 2: Part 2: Make a Slider Widget](https://youtu.be/QjccJl_7Jco) 79 | 80 | ## Further reading about Components 81 | 1. [Streamlit Components - API Documentation](https://docs.streamlit.io/library/components) 82 | 2. [Featured Streamlit Components](https://streamlit.io/components) 83 | 3. [Streamlit Components - Community Tracker](https://discuss.streamlit.io/t/streamlit-components-community-tracker/4634) 84 | 4. [`streamlit_pandas_profiling`](https://share.streamlit.io/okld/streamlit-gallery/main?p=pandas-profiling) 85 | -------------------------------------------------------------------------------- /content/Day15.md: -------------------------------------------------------------------------------- 1 | # st.latex 2 | 3 | `st.latex` display mathematical expressions formatted as LaTeX. 4 | 5 | ## What we're building? 6 | 7 | A simple app that displays a mathematical equation using LaTeX syntax via the `st.latex` command. 8 | 9 | ## Demo app 10 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.latex/) 11 | 12 | ## Code 13 | Here's how to use `st.latex`: 14 | ```python 15 | import streamlit as st 16 | 17 | st.header('st.latex') 18 | 19 | st.latex(r''' 20 | a + ar + a r^2 + a r^3 + \cdots + a r^{n-1} = 21 | \sum_{k=0}^{n-1} ar^k = 22 | a \left(\frac{1-r^{n}}{1-r}\right) 23 | ''') 24 | ``` 25 | 26 | ## Line-by-line explanation 27 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 28 | ```python 29 | import streamlit as st 30 | ``` 31 | 32 | This is followed by creating a header text for the app: 33 | ```python 34 | st.header('st.latex') 35 | ``` 36 | 37 | Next, we're displaying the mathematical equation via `st.latex`: 38 | ```python 39 | st.latex(r''' 40 | a + ar + a r^2 + a r^3 + \cdots + a r^{n-1} = 41 | \sum_{k=0}^{n-1} ar^k = 42 | a \left(\frac{1-r^{n}}{1-r}\right) 43 | ''') 44 | ``` 45 | 46 | ## References 47 | - Read more about [`st.latex`](https://docs.streamlit.io/library/api-reference/text/st.latex) in the Streamlit API Documentation. 48 | -------------------------------------------------------------------------------- /content/Day16.md: -------------------------------------------------------------------------------- 1 | # Customizing the theme of Streamlit apps 2 | 3 | We can customize the theme by adjusting parameters in `config.toml`, which is a configuration file stored in the same folder as the app in the `.streamlit` folder. 4 | 5 | ## What we're building? 6 | 7 | A simple app that shows the result of our theme customization. This is made possible by customizing the HTML HEX code inside the [`.streamlit/config.toml`](https://github.com/dataprofessor/streamlit-custom-theme/blob/master/.streamlit/config.toml) file. 8 | 9 | ## Demo app 10 | 11 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/streamlit-custom-theme/) 12 | 13 | ## Code 14 | Here's the code to the [`streamlit_app.py`](https://github.com/dataprofessor/streamlit-custom-theme/blob/master/streamlit_app.py) file: 15 | ```python 16 | import streamlit as st 17 | 18 | st.title('Customizing the theme of Streamlit apps') 19 | 20 | st.write('Contents of the `.streamlit/config.toml` file of this app') 21 | 22 | st.code(""" 23 | [theme] 24 | primaryColor="#F39C12" 25 | backgroundColor="#2E86C1" 26 | secondaryBackgroundColor="#AED6F1" 27 | textColor="#FFFFFF" 28 | font="monospace" 29 | """) 30 | 31 | number = st.sidebar.slider('Select a number:', 0, 10, 5) 32 | st.write('Selected number from slider widget is:', number) 33 | ``` 34 | 35 | Here's the code to the [`.streamlit/config.toml`](https://github.com/dataprofessor/streamlit-custom-theme/blob/master/.streamlit/config.toml) file: 36 | ```python 37 | [theme] 38 | primaryColor="#F39C12" 39 | backgroundColor="#2E86C1" 40 | secondaryBackgroundColor="#AED6F1" 41 | textColor="#FFFFFF" 42 | font="monospace" 43 | ``` 44 | 45 | ## Line-by-line explanation 46 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 47 | ```python 48 | import streamlit as st 49 | ``` 50 | 51 | This is followed by creating a title text for the app: 52 | ```python 53 | st.title('Theming with config.toml') 54 | ``` 55 | 56 | Next, we're going to show the contents of the `.streamlit/config.toml` file which we'll first display a note of this via `st.write` followed by the actual code via `st.code`: 57 | ```python 58 | st.write('Contents of the ./streamlit/config.toml file of this app') 59 | 60 | st.code(""" 61 | [theme] 62 | primaryColor="#F39C12" 63 | backgroundColor="#2E86C1" 64 | secondaryBackgroundColor="#AED6F1" 65 | textColor="#FFFFFF" 66 | font="monospace" 67 | """) 68 | ``` 69 | 70 | Finally, we're creating a slider widget in the sidebar followed by displaying the selected number: 71 | ```python 72 | number = st.sidebar.slider('Select a number:', 0, 10, 5) 73 | st.write('Selected number from slider widget is:', number) 74 | ``` 75 | 76 | Let's now take a look at the custom colors that we've used in this app, which is specified in the `.streamlit/config.toml` file: 77 | - `primaryColor="#F39C12"` - This sets the primary color to orange. Notice the orange colors in the slider widget. 78 | - `backgroundColor="#2E86C1"` - This sets the background color to blue. Notice the main panel has a blue background color. 79 | - `secondaryBackgroundColor="#AED6F1"` - This sets the secondary background color to dark gray. Notice the gray background color of the sidebar and the background color of the code box in the main panel. 80 | - `textColor="#FFFFFF"` - The text color is set to white. 81 | - `font="monospace"` - This sets the font to monospace. 82 | 83 | 84 | ## Further reading 85 | - [Theming](https://docs.streamlit.io/library/advanced-features/theming) 86 | - [HTML Color Codes](https://htmlcolorcodes.com/) is a great tool for selecting colors of interest. 87 | -------------------------------------------------------------------------------- /content/Day17.md: -------------------------------------------------------------------------------- 1 | # st.secrets 2 | 3 | `st.secrets` allows you to store confidential information such as API keys, database passwords or other credentials. 4 | 5 | ## Demo app 6 | 7 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.secrets/) 8 | 9 | ## Code 10 | Here's how to use `st.secrets`: 11 | ```python 12 | import streamlit as st 13 | 14 | st.title('st.secrets') 15 | 16 | st.write(st.secrets['message']) 17 | ``` 18 | 19 | ## Line-by-line explanation 20 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 21 | ```python 22 | import streamlit as st 23 | ``` 24 | 25 | This is followed by creating a title text for the app: 26 | ```python 27 | st.title('st.secrets') 28 | ``` 29 | 30 | Finally, we'll be displaying the stored secrets: 31 | ```python 32 | st.write(st.secrets['message']) 33 | ``` 34 | 35 | It should be noted that, secrets can be stored in Streamlit Community Cloud as shown in the screenshots shown below. 36 | 37 | If working locally, they can be stored in `.streamlit/secrets.toml`, but make sure to avoid uploading this to a GitHub repo when deploying the app. 38 | 39 | ## Further reading 40 | - [Add secrets to your Streamlit apps](https://blog.streamlit.io/secrets-in-sharing-apps/) 41 | - [Secrets management](https://docs.streamlit.io/streamlit-cloud/get-started/deploy-an-app/connect-to-data-sources/secrets-management) 42 | -------------------------------------------------------------------------------- /content/Day18.md: -------------------------------------------------------------------------------- 1 | # st.file_uploader 2 | 3 | `st.file_uploader` displays a file uploader widget [[1](https://docs.streamlit.io/library/api-reference/widgets/st.file_uploader)]. 4 | 5 | By default, uploaded files are limited to 200MB. You can configure this using the server.maxUploadSize config option. For more info on how to set config options, see [[2](https://docs.streamlit.io/library/advanced-features/configuration#set-configuration-options)]. 6 | 7 | ## Demo app 8 | 9 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.file_uploader/) 10 | 11 | ## Code 12 | Here's how to use `st.file_uploader`: 13 | ```python 14 | import streamlit as st 15 | import pandas as pd 16 | 17 | st.title('st.file_uploader') 18 | 19 | st.subheader('Input CSV') 20 | uploaded_file = st.file_uploader("Choose a file") 21 | 22 | if uploaded_file is not None: 23 | df = pd.read_csv(uploaded_file) 24 | st.subheader('DataFrame') 25 | st.write(df) 26 | st.subheader('Descriptive Statistics') 27 | st.write(df.describe()) 28 | else: 29 | st.info('☝️ Upload a CSV file') 30 | ``` 31 | 32 | ## Line-by-line explanation 33 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` and other prerequisite library like so: 34 | ```python 35 | import streamlit as st 36 | import pandas as pd 37 | ``` 38 | 39 | This is followed by creating a title text for the app: 40 | ```python 41 | st.title('st.file_uploader') 42 | ``` 43 | 44 | Next, we'll use `st.file_uploader` to display a file uploader widget for accepting user input file: 45 | ```python 46 | st.subheader('Input CSV') 47 | uploaded_file = st.file_uploader("Choose a file") 48 | ``` 49 | 50 | Finally, we define conditional statements for initially displaying a welcome message inviting users to upload their file (as implemented in the `else` condition). Upon file upload, the `if` statements are activated and the CSV file is read by the `pandas` library and displayed via the `st.write` command. 51 | ```python 52 | if uploaded_file is not None: 53 | df = pd.read_csv(uploaded_file) 54 | st.subheader('DataFrame') 55 | st.write(df) 56 | st.subheader('Descriptive Statistics') 57 | st.write(df.describe()) 58 | else: 59 | st.info('☝️ Upload a CSV file') 60 | ``` 61 | 62 | ## Further reading 63 | 1. [`st.file_uploader`](https://docs.streamlit.io/library/api-reference/widgets/st.file_uploader) 64 | 2. [Set configuration options](https://docs.streamlit.io/library/advanced-features/configuration#set-configuration-options) 65 | -------------------------------------------------------------------------------- /content/Day19.md: -------------------------------------------------------------------------------- 1 | # How to layout your Streamlit app 2 | 3 | In this tutorial, we're going to use the following commands to layout our Streamlit app: 4 | - `st.set_page_config(layout="wide")` - Displays the contents of the app in wide mode (otherwise by default, the contents are encapsulated in a fixed width box. 5 | - `st.sidebar` - Places the widgets or text/image displays in the sidebar. 6 | - `st.expander` - Places text/image displays inside a collapsible container box. 7 | - `st.columns` - Creates a tabular space (or column) within which contents can be placed inside. 8 | 9 | ## Demo app 10 | 11 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/streamlit-layout/) 12 | 13 | ## Code 14 | Here's how to customize the layout of your Streamlit app: 15 | ```python 16 | import streamlit as st 17 | 18 | st.set_page_config(layout="wide") 19 | 20 | st.title('How to layout your Streamlit app') 21 | 22 | with st.expander('About this app'): 23 | st.write('This app shows the various ways on how you can layout your Streamlit app.') 24 | st.image('https://streamlit.io/images/brand/streamlit-logo-secondary-colormark-darktext.png', width=250) 25 | 26 | st.sidebar.header('Input') 27 | user_name = st.sidebar.text_input('What is your name?') 28 | user_emoji = st.sidebar.selectbox('Choose an emoji', ['', '😄', '😆', '😊', '😍', '😴', '😕', '😱']) 29 | user_food = st.sidebar.selectbox('What is your favorite food?', ['', 'Tom Yum Kung', 'Burrito', 'Lasagna', 'Hamburger', 'Pizza']) 30 | 31 | st.header('Output') 32 | 33 | col1, col2, col3 = st.columns(3) 34 | 35 | with col1: 36 | if user_name != '': 37 | st.write(f'👋 Hello {user_name}!') 38 | else: 39 | st.write('👈 Please enter your **name**!') 40 | 41 | with col2: 42 | if user_emoji != '': 43 | st.write(f'{user_emoji} is your favorite **emoji**!') 44 | else: 45 | st.write('👈 Please choose an **emoji**!') 46 | 47 | with col3: 48 | if user_food != '': 49 | st.write(f'🍴 **{user_food}** is your favorite **food**!') 50 | else: 51 | st.write('👈 Please choose your favorite **food**!') 52 | ``` 53 | 54 | ## Line-by-line explanation 55 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 56 | ```python 57 | import streamlit as st 58 | ``` 59 | 60 | We'll start by first defining the page layout to be displayed in the `wide` mode, which allows the page content to expand to the browser's width. 61 | ```python 62 | st.set_page_config(layout="wide") 63 | ``` 64 | 65 | Next, we'll give the Streamlit app a title. 66 | ```python 67 | st.title('How to layout your Streamlit app') 68 | ``` 69 | 70 | An expandable box titled `About this app` is placed under the app title. Upon expansion, we'll see additional details inside. 71 | ```python 72 | with st.expander('About this app'): 73 | st.write('This app shows the various ways on how you can layout your Streamlit app.') 74 | st.image('https://streamlit.io/images/brand/streamlit-logo-secondary-colormark-darktext.png', width=250) 75 | ``` 76 | 77 | Input widgets for accepting user input is placed in the sidebar as specified by using the `st.sidebar` command before the Streamlit commands `text_input` and `selectbox`. Input values entered or selected by the user are assigned and stored in the `user_name`, `user_emoji` and `user_food` variables. 78 | ```python 79 | st.sidebar.header('Input') 80 | user_name = st.sidebar.text_input('What is your name?') 81 | user_emoji = st.sidebar.selectbox('Choose an emoji', ['', '😄', '😆', '😊', '😍', '😴', '😕', '😱']) 82 | user_food = st.sidebar.selectbox('What is your favorite food?', ['', 'Tom Yum Kung', 'Burrito', 'Lasagna', 'Hamburger', 'Pizza']) 83 | ``` 84 | 85 | Finally, we'll create 3 columns using the `st.columns` command which corresponds to `col1`, `col2` and `col3`. Then, we assign contents to each of the column by creating individual code blocks starting with the `with` statement. Underneath this, we create conditional statements that display 1 of 2 alternative text depending on whether the user had provided their input data (specified in the sidebar) or not. By default, the page displays text under the `else` statement. Upon providing user input, the corresponding information that the user gives to the app is displayed under the `Output` header text. 86 | ```python 87 | st.header('Output') 88 | 89 | col1, col2, col3 = st.columns(3) 90 | 91 | with col1: 92 | if user_name != '': 93 | st.write(f'👋 Hello {user_name}!') 94 | else: 95 | st.write('👈 Please enter your **name**!') 96 | 97 | with col2: 98 | if user_emoji != '': 99 | st.write(f'{user_emoji} is your favorite **emoji**!') 100 | else: 101 | st.write('👈 Please choose an **emoji**!') 102 | 103 | with col3: 104 | if user_food != '': 105 | st.write(f'🍴 **{user_food}** is your favorite **food**!') 106 | else: 107 | st.write('👈 Please choose your favorite **food**!') 108 | ``` 109 | It is also worthy to note that `f` strings were used to combine pre-canned text together with the user provided values. 110 | 111 | ## Further reading 112 | - [Layouts and Containers](https://docs.streamlit.io/library/api-reference/layout) 113 | -------------------------------------------------------------------------------- /content/Day2.md: -------------------------------------------------------------------------------- 1 | # Building your first Streamlit app 2 | 3 | ## Fire up your IDE 4 | 5 | Fire up your IDE whether it be Atom, VS Code or even a cloud IDE such as GitPod or GitHub.dev. 6 | 7 | Create a file called `streamlit_app.py` 8 | 9 | ## Entering your first lines of code 10 | 11 | To the newly created file, enter the following lines of code: 12 | 13 | ``` 14 | import streamlit as st 15 | 16 | st.write('Hello world!') 17 | ``` 18 | 19 | Save the file. 20 | 21 | ## Fire up the command line terminal 22 | 23 | To the terminal, enter the following: 24 | 25 | ``` 26 | streamlit run streamlit_app.py 27 | ``` 28 | 29 | A browser window should pop-up showing the newly created Streamlit app. 30 | 31 | **Congratulations!** You have just created your first Streamlit app! 32 | -------------------------------------------------------------------------------- /content/Day20.md: -------------------------------------------------------------------------------- 1 | # Tech Twitter Space on What is Streamlit? 2 | ## (Hosted by Francesco Ciulla) 3 | 4 | Join us for a discussion about Streamlit with our host [Francesco Ciulla](https://twitter.com/FrancescoCiull4). 5 | 6 | 👉 Link: https://twitter.com/i/spaces/1dRJZlbglXMKB 7 | -------------------------------------------------------------------------------- /content/Day21.md: -------------------------------------------------------------------------------- 1 | # st.progress 2 | 3 | `st.progress` displays a progress bar that updates graphically as the iteration progresses. 4 | 5 | ## Demo app 6 | 7 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.progress/) 8 | 9 | ## Code 10 | Here's how to use `st.progress`: 11 | ```python 12 | import streamlit as st 13 | import time 14 | 15 | st.title('st.progress') 16 | 17 | with st.expander('About this app'): 18 | st.write('You can now display the progress of your calculations in a Streamlit app with the `st.progress` command.') 19 | 20 | my_bar = st.progress(0) 21 | 22 | for percent_complete in range(100): 23 | time.sleep(0.05) 24 | my_bar.progress(percent_complete + 1) 25 | 26 | st.balloons() 27 | ``` 28 | 29 | ## Line-by-line explanation 30 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` along with the `time` library like so: 31 | ```python 32 | import streamlit as st 33 | import time 34 | ``` 35 | 36 | Next, we create a title text for the app: 37 | ```python 38 | st.title('st.progress') 39 | ``` 40 | 41 | An **About box** is created using `st.expander` and description is displayed via `st.write`: 42 | ```python 43 | with st.expander('About this app'): 44 | st.write('You can now display the progress of your calculations in a Streamlit app with the `st.progress` command.') 45 | ``` 46 | 47 | Finally, we define a progress bar and instantiate it with a starting value of `0`. Then, a `for` loop will iterate from `0` until `100` is reached. In each iteration, we use `time.sleep(0.05)` to allow the app to wait for `0.05` before adding a value of `1` to the `my_bar` progress bar and in doing so the graphical display of the bar increases with each iteration. 48 | ```python 49 | my_bar = st.progress(0) 50 | 51 | for percent_complete in range(100): 52 | time.sleep(0.05) 53 | my_bar.progress(percent_complete + 1) 54 | 55 | st.balloons() 56 | ``` 57 | 58 | ## Further reading 59 | - [`st.progress`](https://docs.streamlit.io/library/api-reference/status/st.progress) 60 | -------------------------------------------------------------------------------- /content/Day22.md: -------------------------------------------------------------------------------- 1 | # st.form 2 | 3 | `st.form` creates a form that batches elements together with a "Submit" button. 4 | 5 | Typically, whenever a user interacts with a widget, the Streamlit app is rerun. 6 | 7 | A form is a container that visually groups other elements and widgets together, and contains a Submit button. Herein, a user can interacts with one or more widgets for as many times as they like without causing a rerun. Finally, when the form's Submit button is pressed, all widget values inside the form will be sent to Streamlit in a single batch. 8 | 9 | To add elements to a form object, you can use the `with` notation (preferred) or you could use it as an object notation by just calling methods directly on the form (by first assigning it to a variable and subsequently applying Streamlit methods on it). See in the example app. 10 | 11 | Forms have a few constraints: 12 | - Every form must contain a `st.form_submit_button`. 13 | - `st.button` and `st.download_button` cannot be added to a form. 14 | - Forms can appear anywhere in your app (sidebar, columns, etc), but they cannot be embedded inside other forms. 15 | 16 | For more information about forms, check out our [blog post](https://blog.streamlit.io/introducing-submit-button-and-forms/). 17 | 18 | ## Demo app 19 | 20 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.form/) 21 | 22 | ## Code 23 | Here's how to use `st.form`: 24 | ```python 25 | import streamlit as st 26 | 27 | st.title('st.form') 28 | 29 | # Full example of using the with notation 30 | st.header('1. Example of using `with` notation') 31 | st.subheader('Coffee machine') 32 | 33 | with st.form('my_form'): 34 | st.subheader('**Order your coffee**') 35 | 36 | # Input widgets 37 | coffee_bean_val = st.selectbox('Coffee bean', ['Arabica', 'Robusta']) 38 | coffee_roast_val = st.selectbox('Coffee roast', ['Light', 'Medium', 'Dark']) 39 | brewing_val = st.selectbox('Brewing method', ['Aeropress', 'Drip', 'French press', 'Moka pot', 'Siphon']) 40 | serving_type_val = st.selectbox('Serving format', ['Hot', 'Iced', 'Frappe']) 41 | milk_val = st.select_slider('Milk intensity', ['None', 'Low', 'Medium', 'High']) 42 | owncup_val = st.checkbox('Bring own cup') 43 | 44 | # Every form must have a submit button 45 | submitted = st.form_submit_button('Submit') 46 | 47 | if submitted: 48 | st.markdown(f''' 49 | ☕ You have ordered: 50 | - Coffee bean: `{coffee_bean_val}` 51 | - Coffee roast: `{coffee_roast_val}` 52 | - Brewing: `{brewing_val}` 53 | - Serving type: `{serving_type_val}` 54 | - Milk: `{milk_val}` 55 | - Bring own cup: `{owncup_val}` 56 | ''') 57 | else: 58 | st.write('☝️ Place your order!') 59 | 60 | 61 | # Short example of using an object notation 62 | st.header('2. Example of object notation') 63 | 64 | form = st.form('my_form_2') 65 | selected_val = form.slider('Select a value') 66 | form.form_submit_button('Submit') 67 | 68 | st.write('Selected value: ', selected_val) 69 | ``` 70 | 71 | ## Line-by-line explanation 72 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 73 | ```python 74 | import streamlit as st 75 | ``` 76 | 77 | This is followed by creating a title text for the app: 78 | ```python 79 | st.title('st.form') 80 | ``` 81 | 82 | ### First example 83 | Let's start with the first example, here we'll apply the `st.form` command via the `with` notation. Inside the form, we'll start with writing a subheader `Order your coffee` then create several input widgets (`st.selectbox`, `st.select_slider` and `st.checkbox`) to collect information about the coffee order. Finally, a submit button is created via the `st.form_submit_button` command, which when clicked on will send all user input as a single batch of information to the app for processing. 84 | ```python 85 | # Full example of using the with notation 86 | st.header('1. Example of using `with` notation') 87 | st.subheader('Coffee machine') 88 | 89 | with st.form('my_form'): 90 | st.subheader('**Order your coffee**') 91 | 92 | # Input widgets 93 | coffee_bean_val = st.selectbox('Coffee bean', ['Arabica', 'Robusta']) 94 | coffee_roast_val = st.selectbox('Coffee roast', ['Light', 'Medium', 'Dark']) 95 | brewing_val = st.selectbox('Brewing method', ['Aeropress', 'Drip', 'French press', 'Moka pot', 'Siphon']) 96 | serving_type_val = st.selectbox('Serving format', ['Hot', 'Iced', 'Frappe']) 97 | milk_val = st.select_slider('Milk intensity', ['None', 'Low', 'Medium', 'High']) 98 | owncup_val = st.checkbox('Bring own cup') 99 | 100 | # Every form must have a submit button. 101 | submitted = st.form_submit_button('Submit') 102 | ``` 103 | 104 | Next, we'll add the logic of what happen's after the submit button is clicked on. By default, whenever the Streamlit app is loaded the `else` statement will be run and we see a message `☝️ Place your order!`. Whereas upon clicking on the submit button, all user provided input via the various widgets are stored in several variables (e.g. `coffee_bean_val`, `coffee_roast_val`, etc.) and printed out via the `st.markdown` command with the help of f-string. 105 | ```python 106 | if submitted: 107 | st.markdown(f''' 108 | ☕ You have ordered: 109 | - Coffee bean: `{coffee_bean_val}` 110 | - Coffee roast: `{coffee_roast_val}` 111 | - Brewing: `{brewing_val}` 112 | - Serving type: `{serving_type_val}` 113 | - Milk: `{milk_val}` 114 | - Bring own cup: `{owncup_val}` 115 | ''') 116 | else: 117 | st.write('☝️ Place your order!') 118 | ``` 119 | 120 | 121 | ### Second example 122 | Let's now proceed to the second example on using the `st.form` as an object notation. Here, the `st.form` command is assigned to the `form` variable. Subsequently, various Streamlit commands such as `slider` or `form_submit_button` is applied on the `form` variable. 123 | ```python 124 | # Short example of using an object notation 125 | st.header('2. Example of object notation') 126 | 127 | form = st.form('my_form_2') 128 | selected_val = form.slider('Select a value') 129 | form.form_submit_button('Submit') 130 | 131 | st.write('Selected value: ', selected_val) 132 | ``` 133 | 134 | ## Further reading 135 | - [`st.form`](https://docs.streamlit.io/library/api-reference/control-flow/st.form) 136 | - [Introducing Submit button and Forms](https://blog.streamlit.io/introducing-submit-button-and-forms/) 137 | -------------------------------------------------------------------------------- /content/Day23.md: -------------------------------------------------------------------------------- 1 | # st.experimental_get_query_params 2 | 3 | `st.experimental_get_query_params` allows the retrieval of query parameters directly from the URL of the user's browser. 4 | 5 | ## Demo app 6 | 7 | 1. The following link loads the demo app with no query parameters (notice the error message): 8 | 9 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.experimental_get_query_params/) 10 | 11 | 2. The following link loads the demo app with query parameters (no error message here): 12 | 13 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](http://share.streamlit.io/dataprofessor/st.experimental_get_query_params/?firstname=Jack&surname=Beanstalk) 14 | 15 | ## Code 16 | Here's how to use `st.experimental_get_query_params`: 17 | ```python 18 | import streamlit as st 19 | 20 | st.title('st.experimental_get_query_params') 21 | 22 | with st.expander('About this app'): 23 | st.write("`st.experimental_get_query_params` allows the retrieval of query parameters directly from the URL of the user's browser.") 24 | 25 | # 1. Instructions 26 | st.header('1. Instructions') 27 | st.markdown(''' 28 | In the above URL bar of your internet browser, append the following: 29 | `?firstname=Jack&surname=Beanstalk` 30 | after the base URL `http://share.streamlit.io/dataprofessor/st.experimental_get_query_params/` 31 | such that it becomes 32 | `http://share.streamlit.io/dataprofessor/st.experimental_get_query_params/?firstname=Jack&surname=Beanstalk` 33 | ''') 34 | 35 | 36 | # 2. Contents of st.experimental_get_query_params 37 | st.header('2. Contents of st.experimental_get_query_params') 38 | st.write(st.experimental_get_query_params()) 39 | 40 | 41 | # 3. Retrieving and displaying information from the URL 42 | st.header('3. Retrieving and displaying information from the URL') 43 | 44 | firstname = st.experimental_get_query_params()['firstname'][0] 45 | surname = st.experimental_get_query_params()['surname'][0] 46 | 47 | st.write(f'Hello **{firstname} {surname}**, how are you?') 48 | ``` 49 | 50 | ## Line-by-line explanation 51 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 52 | ```python 53 | import streamlit as st 54 | ``` 55 | 56 | Next, we'll give the app a title: 57 | ```python 58 | st.title('st.experimental_get_query_params') 59 | ``` 60 | 61 | Let's also add an About drop-down box: 62 | ```python 63 | with st.expander('About this app'): 64 | st.write("`st.experimental_get_query_params` allows the retrieval of query parameters directly from the URL of the user's browser.") 65 | ``` 66 | 67 | Then, we'll provide instructions to visitors of the app on how they can pass query parameters directly to the URL: 68 | ```python 69 | # 1. Instructions 70 | st.header('1. Instructions') 71 | st.markdown(''' 72 | In the above URL bar of your internet browser, append the following: 73 | `?name=Jack&surname=Beanstalk` 74 | after the base URL `http://share.streamlit.io/dataprofessor/st.experimental_get_query_params/` 75 | such that it becomes 76 | `http://share.streamlit.io/dataprofessor/st.experimental_get_query_params/?firstname=Jack&surname=Beanstalk` 77 | ''') 78 | ``` 79 | 80 | Subsequently, we'll display the contents of the `st.experimental_get_query_params` command. 81 | ```python 82 | # 2. Contents of st.experimental_get_query_params 83 | st.header('2. Contents of st.experimental_get_query_params') 84 | st.write(st.experimental_get_query_params()) 85 | ``` 86 | 87 | Finally, we'll select and display selective information from the URL's query parameter: 88 | ```python 89 | # 3. Retrieving and displaying information from the URL 90 | st.header('3. Retrieving and displaying information from the URL') 91 | 92 | firstname = st.experimental_get_query_params()['firstname'][0] 93 | surname = st.experimental_get_query_params()['surname'][0] 94 | 95 | st.write(f'Hello **{firstname} {surname}**, how are you?') 96 | ``` 97 | 98 | ## Further reading 99 | - [`st.experimental_get_query_params`](https://docs.streamlit.io/library/api-reference/utilities/st.experimental_get_query_params) 100 | -------------------------------------------------------------------------------- /content/Day24.md: -------------------------------------------------------------------------------- 1 | # st.cache 2 | 3 | `st.cache` allows you to optimize the performance of your Streamlit app. 4 | 5 | Streamlit provides a caching mechanism that allows your app to stay performant even when loading data from the web, manipulating large datasets, or performing expensive computations. This is done with the `@st.cache` decorator. 6 | 7 | When you mark a function with the @st.cache decorator, it tells Streamlit that whenever the function is called it needs to check a few things: 8 | 9 | 1. The input parameters that you called the function with 10 | 2. The value of any external variable used in the function 11 | 3. The body of the function 12 | 4. The body of any function used inside the cached function 13 | 14 | If this is the first time Streamlit has seen these four components with these exact values and in this exact combination and order, it runs the function and stores the result in a local cache. Then, next time the cached function is called, if none of these components changed, Streamlit will just skip executing the function altogether and, instead, return the output previously stored in the cache. 15 | 16 | The way Streamlit keeps track of changes in these components is through hashing. Think of the cache as an in-memory key-value store, where the key is a hash of all of the above and the value is the actual output object passed by reference. 17 | 18 | Finally, `@st.cache` supports arguments to configure the cache's behavior. You can find more information on those in our API reference. 19 | 20 | ## How to use? 21 | 22 | You can simply add `st.cache` decorator on the preceding line of a custom function that you define in your Streamlit app. See the example below. 23 | 24 | ## Demo app 25 | 26 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.cache/) 27 | 28 | ## Code 29 | Here's how to use `st.cache`: 30 | ```python 31 | import streamlit as st 32 | import numpy as np 33 | import pandas as pd 34 | from time import time 35 | 36 | st.title('st.cache') 37 | 38 | # Using cache 39 | a0 = time() 40 | st.subheader('Using st.cache') 41 | 42 | @st.cache(suppress_st_warning=True) 43 | def load_data_a(): 44 | df = pd.DataFrame( 45 | np.random.rand(2000000, 5), 46 | columns=['a', 'b', 'c', 'd', 'e'] 47 | ) 48 | return df 49 | 50 | st.write(load_data_a()) 51 | a1 = time() 52 | st.info(a1-a0) 53 | 54 | 55 | # Not using cache 56 | b0 = time() 57 | st.subheader('Not using st.cache') 58 | 59 | def load_data_b(): 60 | df = pd.DataFrame( 61 | np.random.rand(2000000, 5), 62 | columns=['a', 'b', 'c', 'd', 'e'] 63 | ) 64 | return df 65 | 66 | st.write(load_data_b()) 67 | b1 = time() 68 | st.info(b1-b0) 69 | ``` 70 | 71 | ## Line-by-line explanation 72 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` as well as other libraries used in the app like so: 73 | ```python 74 | import streamlit as st 75 | import numpy as np 76 | import pandas as pd 77 | from time import time 78 | ``` 79 | 80 | This is followed by creating a title text for the app: 81 | ```python 82 | st.title('Streamlit Cache') 83 | ``` 84 | 85 | Next, we'll define 2 custom functions for generating a large DataFrame where the first one makes use of the `st.cache` decorator while the second does not: 86 | ```python 87 | @st.cache(suppress_st_warning=True) 88 | def load_data_a(): 89 | df = pd.DataFrame( 90 | np.random.rand(1000000, 5), 91 | columns=['a', 'b', 'c', 'd', 'e'] 92 | ) 93 | return df 94 | 95 | def load_data_b(): 96 | df = pd.DataFrame( 97 | np.random.rand(1000000, 5), 98 | columns=['a', 'b', 'c', 'd', 'e'] 99 | ) 100 | return df 101 | ``` 102 | 103 | Finally, we run the custom function while also timing the run time using the `time()` command. 104 | ```python 105 | # Using cache 106 | a0 = time() 107 | st.subheader('Using st.cache') 108 | 109 | # We insert the load_data_a function here 110 | 111 | st.write(load_data_a()) 112 | a1 = time() 113 | st.info(a1-a0) 114 | 115 | # Not using cache 116 | b0 = time() 117 | st.subheader('Not using st.cache') 118 | 119 | # We insert the load_data_b function here 120 | 121 | st.write(load_data_b()) 122 | b1 = time() 123 | st.info(b1-b0) 124 | ``` 125 | 126 | Notice how the first run may provide roughly similar run time. Reload the app and notice how the run time changes when using the `st.cache` decorator. Did you observe any speed increase? 127 | 128 | ## Further reading 129 | - [`st.cache` API Documentation](https://docs.streamlit.io/library/api-reference/performance/st.cache) 130 | - [Optimize performance with `st.cache`](https://docs.streamlit.io/library/advanced-features/caching) 131 | - [Experimental cache primitives](https://docs.streamlit.io/library/advanced-features/experimental-cache-primitives) 132 | - [`st.experimental_memo`](https://docs.streamlit.io/library/api-reference/performance/st.experimental_memo) 133 | - [`st.experimental_singleton`](https://docs.streamlit.io/library/api-reference/performance/st.experimental_singleton) 134 | -------------------------------------------------------------------------------- /content/Day25.md: -------------------------------------------------------------------------------- 1 | # st.session_state 2 | 3 | We define access to a Streamlit app in a browser tab as a session. For each browser tab that connects to the Streamlit server, a new session is created. Streamlit reruns your script from top to bottom every time you interact with your app. Each reruns takes place in a blank slate: no variables are shared between runs. 4 | 5 | Session State is a way to share variables between reruns, for each user session. In addition to the ability to store and persist state, Streamlit also exposes the ability to manipulate state using Callbacks. 6 | 7 | In this tutorial, we will illustrate the usage of Session State and Callbacks as we build a weight conversion app. 8 | 9 | `st.session_state` allows the implementation of session state in a Streamlit app. 10 | 11 | ## Demo app 12 | 13 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.session_state/) 14 | 15 | ## Code 16 | Here's how to use `st.session_state`: 17 | ```python 18 | import streamlit as st 19 | 20 | st.title('st.session_state') 21 | 22 | def lbs_to_kg(): 23 | st.session_state.kg = st.session_state.lbs/2.2046 24 | def kg_to_lbs(): 25 | st.session_state.lbs = st.session_state.kg*2.2046 26 | 27 | st.header('Input') 28 | col1, spacer, col2 = st.columns([2,1,2]) 29 | with col1: 30 | pounds = st.number_input("Pounds:", key = "lbs", on_change = lbs_to_kg) 31 | with col2: 32 | kilogram = st.number_input("Kilograms:", key = "kg", on_change = kg_to_lbs) 33 | 34 | st.header('Output') 35 | st.write("st.session_state object:", st.session_state) 36 | ``` 37 | 38 | ## Line-by-line explanation 39 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 40 | ```python 41 | import streamlit as st 42 | ``` 43 | 44 | Firstly, we'll start by creating the title of the app: 45 | ```python 46 | st.title('st.session_state') 47 | ``` 48 | 49 | Next, we define custom functions for the weight conversion from lbs to kg and vice versa: 50 | ```python 51 | def lbs_to_kg(): 52 | st.session_state.kg = st.session_state.lbs/2.2046 53 | def kg_to_lbs(): 54 | st.session_state.lbs = st.session_state.kg*2.2046 55 | ``` 56 | 57 | Here, we use `st.number_input` to accept numerical inputs of the weight values: 58 | ```python 59 | st.header('Input') 60 | col1, spacer, col2 = st.columns([2,1,2]) 61 | with col1: 62 | pounds = st.number_input("Pounds:", key = "lbs", on_change = lbs_to_kg) 63 | with col2: 64 | kilogram = st.number_input("Kilograms:", key = "kg", on_change = kg_to_lbs) 65 | ``` 66 | The above 2 custom functions will be called upon as soon as a numerical value is entered into the number box created using the `st.number_input` command. Notice how the `on_change` option specifies the 2 custom functions `lbs_to_kg` and `kg_to_lbs`). 67 | 68 | In a nutshell, upon entering a number into the `st.number_input` box the number is converted by these custom functions. 69 | 70 | Finally, the weight values in `kg` and `lbs` units as stored in the session state as `st.session_state.kg` and `st.session_state.lbs` will be printed out via `st.write`: 71 | ```python 72 | st.header('Output') 73 | st.write("st.session_state object:", st.session_state) 74 | ``` 75 | 76 | ## Further reading 77 | - [Session State](https://docs.streamlit.io/library/api-reference/session-state) 78 | - [Add statefulness to apps](https://docs.streamlit.io/library/advanced-features/session-state) 79 | -------------------------------------------------------------------------------- /content/Day26.md: -------------------------------------------------------------------------------- 1 | # How to use API by building the Bored API app 2 | 3 | The Bored API app suggests fun things for you to do when you are bored! 4 | 5 | Technically, it also demonstrates the usage of APIs from within a Streamlit app. 6 | 7 | ## Demo app 8 | 9 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/bored-api-app/) 10 | 11 | ## Code 12 | Here's how to implement the Bored-API app: 13 | ```python 14 | import streamlit as st 15 | import requests 16 | 17 | st.title('🏀 Bored API app') 18 | 19 | st.sidebar.header('Input') 20 | selected_type = st.sidebar.selectbox('Select an activity type', ["education", "recreational", "social", "diy", "charity", "cooking", "relaxation", "music", "busywork"]) 21 | 22 | suggested_activity_url = f'http://www.boredapi.com/api/activity?type={selected_type}' 23 | json_data = requests.get(suggested_activity_url) 24 | suggested_activity = json_data.json() 25 | 26 | c1, c2 = st.columns(2) 27 | with c1: 28 | with st.expander('About this app'): 29 | st.write('Are you bored? The **Bored API app** provides suggestions on activities that you can do when you are bored. This app is powered by the Bored API.') 30 | with c2: 31 | with st.expander('JSON data'): 32 | st.write(suggested_activity) 33 | 34 | st.header('Suggested activity') 35 | st.info(suggested_activity['activity']) 36 | 37 | col1, col2, col3 = st.columns(3) 38 | with col1: 39 | st.metric(label='Number of Participants', value=suggested_activity['participants'], delta='') 40 | with col2: 41 | st.metric(label='Type of Activity', value=suggested_activity['type'].capitalize(), delta='') 42 | with col3: 43 | st.metric(label='Price', value=suggested_activity['price'], delta='') 44 | ``` 45 | 46 | ## Line-by-line explanation 47 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` and the `requests` library like so: 48 | ```python 49 | import streamlit as st 50 | import requests 51 | ``` 52 | 53 | The app's title is displayed via `st.title`: 54 | ```python 55 | st.title('🏀 Bored API app') 56 | ``` 57 | 58 | Next, we'll accept user input on the **activity type** by means of the `st.selectbox` command: 59 | ```python 60 | st.sidebar.header('Input') 61 | selected_type = st.sidebar.selectbox('Select an activity type', ["education", "recreational", "social", "diy", "charity", "cooking", "relaxation", "music", "busywork"]) 62 | ``` 63 | 64 | The selected activity mentioned above is then appended to the URL via an f-string, which is then used to retrieve the resulting JSON data: 65 | ```python 66 | suggested_activity_url = f'http://www.boredapi.com/api/activity?type={selected_type}' 67 | json_data = requests.get(suggested_activity_url) 68 | suggested_activity = json_data.json() 69 | ``` 70 | 71 | Here, we'll display information about the app and the JSON data via the `st.expander` command. 72 | ```python 73 | c1, c2 = st.columns(2) 74 | with c1: 75 | with st.expander('About this app'): 76 | st.write('Are you bored? The **Bored API app** provides suggestions on activities that you can do. This app is powered by the Bored API.') 77 | with c2: 78 | with st.expander('JSON data'): 79 | st.write(suggested_activity) 80 | ``` 81 | 82 | We'll then display a suggested activity like so: 83 | ```python 84 | st.header('Suggested activity') 85 | st.info(suggested_activity['activity']) 86 | ``` 87 | 88 | Finally, we'll also display the accompanying information of the suggested activity such as the `Number of Participants`, `Type of Activity` and `Price`. 89 | ```python 90 | col1, col2, col3 = st.columns(3) 91 | with col1: 92 | st.metric(label='Number of Participants', value=suggested_activity['participants'], delta='') 93 | with col2: 94 | st.metric(label='Type of Activity', value=suggested_activity['type'].capitalize(), delta='') 95 | with col3: 96 | st.metric(label='Price', value=suggested_activity['price'], delta='') 97 | ``` 98 | 99 | ## Further reading 100 | - [Bored API](http://www.boredapi.com/) 101 | -------------------------------------------------------------------------------- /content/Day27.md: -------------------------------------------------------------------------------- 1 | # Build a draggable and resizable dashboard with Streamlit Elements 2 | 3 | Streamlit Elements is a third-party component made by [okld](https://github.com/okld) that gives you the tools to compose beautiful applications and dashboards with Material UI widgets, Monaco editor (Visual Studio Code), Nivo charts, and more. 4 | 5 | ## How to use? 6 | 7 | ### Installation 8 | 9 | The first step is to install Streamlit Elements in your environment: 10 | 11 | ```bash 12 | pip install streamlit-elements==0.1.* 13 | ``` 14 | 15 | It is recommended to pin the version to `0.1.*`, as future versions might introduce breaking API changes. 16 | 17 | ### Usage 18 | 19 | You can refer to [Streamlit Elements README](https://github.com/okld/streamlit-elements#getting-started) for an in-depth usage guide. 20 | 21 | ## What are we building? 22 | 23 | The goal of today's challenge is to create a dashboard composed of three Material UI cards: 24 | 25 | - A first card with a Monaco code editor to input some data ; 26 | - A second card to display that data in a Nivo Bump chart ; 27 | - A third card to show a YouTube video URL defined with a `st.text_input`. 28 | 29 | You can use data generated from Nivo Bump demo there, in 'data' tab: https://nivo.rocks/bump/. 30 | 31 | ## Demo app 32 | 33 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/okld/streamlit-elements-demo/main) 34 | 35 | ## Code with line-by-line explanation 36 | 37 | ```python 38 | # First, we will need the following imports for our application. 39 | 40 | import json 41 | import streamlit as st 42 | from pathlib import Path 43 | 44 | # As for Streamlit Elements, we will need all these objects. 45 | # All available objects and there usage are listed there: https://github.com/okld/streamlit-elements#getting-started 46 | 47 | from streamlit_elements import elements, dashboard, mui, editor, media, lazy, sync, nivo 48 | 49 | # Change page layout to make the dashboard take the whole page. 50 | 51 | st.set_page_config(layout="wide") 52 | 53 | with st.sidebar: 54 | st.title("🗓️ #30DaysOfStreamlit") 55 | st.header("Day 27 - Streamlit Elements") 56 | st.write("Build a draggable and resizable dashboard with Streamlit Elements.") 57 | st.write("---") 58 | 59 | # Define URL for media player. 60 | media_url = st.text_input("Media URL", value="https://www.youtube.com/watch?v=vIQQR_yq-8I") 61 | 62 | # Initialize default data for code editor and chart. 63 | # 64 | # For this tutorial, we will need data for a Nivo Bump chart. 65 | # You can get random data there, in tab 'data': https://nivo.rocks/bump/ 66 | # 67 | # As you will see below, this session state item will be updated when our 68 | # code editor change, and it will be read by Nivo Bump chart to draw the data. 69 | 70 | if "data" not in st.session_state: 71 | st.session_state.data = Path("data.json").read_text() 72 | 73 | # Define a default dashboard layout. 74 | # Dashboard grid has 12 columns by default. 75 | # 76 | # For more information on available parameters: 77 | # https://github.com/react-grid-layout/react-grid-layout#grid-item-props 78 | 79 | layout = [ 80 | # Editor item is positioned in coordinates x=0 and y=0, and takes 6/12 columns and has a height of 3. 81 | dashboard.Item("editor", 0, 0, 6, 3), 82 | # Chart item is positioned in coordinates x=6 and y=0, and takes 6/12 columns and has a height of 3. 83 | dashboard.Item("chart", 6, 0, 6, 3), 84 | # Media item is positioned in coordinates x=0 and y=3, and takes 6/12 columns and has a height of 4. 85 | dashboard.Item("media", 0, 2, 12, 4), 86 | ] 87 | 88 | # Create a frame to display elements. 89 | 90 | with elements("demo"): 91 | 92 | # Create a new dashboard with the layout specified above. 93 | # 94 | # draggableHandle is a CSS query selector to define the draggable part of each dashboard item. 95 | # Here, elements with a 'draggable' class name will be draggable. 96 | # 97 | # For more information on available parameters for dashboard grid: 98 | # https://github.com/react-grid-layout/react-grid-layout#grid-layout-props 99 | # https://github.com/react-grid-layout/react-grid-layout#responsive-grid-layout-props 100 | 101 | with dashboard.Grid(layout, draggableHandle=".draggable"): 102 | 103 | # First card, the code editor. 104 | # 105 | # We use the 'key' parameter to identify the correct dashboard item. 106 | # 107 | # To make card's content automatically fill the height available, we will use CSS flexbox. 108 | # sx is a parameter available with every Material UI widget to define CSS attributes. 109 | # 110 | # For more information regarding Card, flexbox and sx: 111 | # https://mui.com/components/cards/ 112 | # https://mui.com/system/flexbox/ 113 | # https://mui.com/system/the-sx-prop/ 114 | 115 | with mui.Card(key="editor", sx={"display": "flex", "flexDirection": "column"}): 116 | 117 | # To make this header draggable, we just need to set its classname to 'draggable', 118 | # as defined above in dashboard.Grid's draggableHandle. 119 | 120 | mui.CardHeader(title="Editor", className="draggable") 121 | 122 | # We want to make card's content take all the height available by setting flex CSS value to 1. 123 | # We also want card's content to shrink when the card is shrinked by setting minHeight to 0. 124 | 125 | with mui.CardContent(sx={"flex": 1, "minHeight": 0}): 126 | 127 | # Here is our Monaco code editor. 128 | # 129 | # First, we set the default value to st.session_state.data that we initialized above. 130 | # Second, we define the language to use, JSON here. 131 | # 132 | # Then, we want to retrieve changes made to editor's content. 133 | # By checking Monaco documentation, there is an onChange property that takes a function. 134 | # This function is called everytime a change is made, and the updated content value is passed in 135 | # the first parameter (cf. onChange: https://github.com/suren-atoyan/monaco-react#props) 136 | # 137 | # Streamlit Elements provide a special sync() function. This function creates a callback that will 138 | # automatically forward its parameters to Streamlit's session state items. 139 | # 140 | # Examples 141 | # -------- 142 | # Create a callback that forwards its first parameter to a session state item called "data": 143 | # >>> editor.Monaco(onChange=sync("data")) 144 | # >>> print(st.session_state.data) 145 | # 146 | # Create a callback that forwards its second parameter to a session state item called "ev": 147 | # >>> editor.Monaco(onChange=sync(None, "ev")) 148 | # >>> print(st.session_state.ev) 149 | # 150 | # Create a callback that forwards both of its parameters to session state: 151 | # >>> editor.Monaco(onChange=sync("data", "ev")) 152 | # >>> print(st.session_state.data) 153 | # >>> print(st.session_state.ev) 154 | # 155 | # Now, there is an issue: onChange is called everytime a change is made, which means everytime 156 | # you type a single character, your entire Streamlit app will rerun. 157 | # 158 | # To avoid this issue, you can tell Streamlit Elements to wait for another event to occur 159 | # (like a button click) to send the updated data, by wrapping your callback with lazy(). 160 | # 161 | # For more information on available parameters for Monaco: 162 | # https://github.com/suren-atoyan/monaco-react 163 | # https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneEditorConstructionOptions.html 164 | 165 | editor.Monaco( 166 | defaultValue=st.session_state.data, 167 | language="json", 168 | onChange=lazy(sync("data")) 169 | ) 170 | 171 | with mui.CardActions: 172 | 173 | # Monaco editor has a lazy callback bound to onChange, which means that even if you change 174 | # Monaco's content, Streamlit won't be notified directly, thus won't reload everytime. 175 | # So we need another non-lazy event to trigger an update. 176 | # 177 | # The solution is to create a button that fires a callback on click. 178 | # Our callback doesn't need to do anything in particular. You can either create an empty 179 | # Python function, or use sync() with no argument. 180 | # 181 | # Now, everytime you will click that button, onClick callback will be fired, but every other 182 | # lazy callbacks that changed in the meantime will also be called. 183 | 184 | mui.Button("Apply changes", onClick=sync()) 185 | 186 | # Second card, the Nivo Bump chart. 187 | # We will use the same flexbox configuration as the first card to auto adjust the content height. 188 | 189 | with mui.Card(key="chart", sx={"display": "flex", "flexDirection": "column"}): 190 | 191 | # To make this header draggable, we just need to set its classname to 'draggable', 192 | # as defined above in dashboard.Grid's draggableHandle. 193 | 194 | mui.CardHeader(title="Chart", className="draggable") 195 | 196 | # Like above, we want to make our content grow and shrink as the user resizes the card, 197 | # by setting flex to 1 and minHeight to 0. 198 | 199 | with mui.CardContent(sx={"flex": 1, "minHeight": 0}): 200 | 201 | # This is where we will draw our Bump chart. 202 | # 203 | # For this exercise, we can just adapt Nivo's example and make it work with Streamlit Elements. 204 | # Nivo's example is available in the 'code' tab there: https://nivo.rocks/bump/ 205 | # 206 | # Data takes a dictionary as parameter, so we need to convert our JSON data from a string to 207 | # a Python dictionary first, with `json.loads()`. 208 | # 209 | # For more information regarding other available Nivo charts: 210 | # https://nivo.rocks/ 211 | 212 | nivo.Bump( 213 | data=json.loads(st.session_state.data), 214 | colors={ "scheme": "spectral" }, 215 | lineWidth=3, 216 | activeLineWidth=6, 217 | inactiveLineWidth=3, 218 | inactiveOpacity=0.15, 219 | pointSize=10, 220 | activePointSize=16, 221 | inactivePointSize=0, 222 | pointColor={ "theme": "background" }, 223 | pointBorderWidth=3, 224 | activePointBorderWidth=3, 225 | pointBorderColor={ "from": "serie.color" }, 226 | axisTop={ 227 | "tickSize": 5, 228 | "tickPadding": 5, 229 | "tickRotation": 0, 230 | "legend": "", 231 | "legendPosition": "middle", 232 | "legendOffset": -36 233 | }, 234 | axisBottom={ 235 | "tickSize": 5, 236 | "tickPadding": 5, 237 | "tickRotation": 0, 238 | "legend": "", 239 | "legendPosition": "middle", 240 | "legendOffset": 32 241 | }, 242 | axisLeft={ 243 | "tickSize": 5, 244 | "tickPadding": 5, 245 | "tickRotation": 0, 246 | "legend": "ranking", 247 | "legendPosition": "middle", 248 | "legendOffset": -40 249 | }, 250 | margin={ "top": 40, "right": 100, "bottom": 40, "left": 60 }, 251 | axisRight=None, 252 | ) 253 | 254 | # Third element of the dashboard, the Media player. 255 | 256 | with mui.Card(key="media", sx={"display": "flex", "flexDirection": "column"}): 257 | mui.CardHeader(title="Media Player", className="draggable") 258 | with mui.CardContent(sx={"flex": 1, "minHeight": 0}): 259 | 260 | # This element is powered by ReactPlayer, it supports many more players other 261 | # than YouTube. You can check it out there: https://github.com/cookpete/react-player#props 262 | 263 | media.Player(url=media_url, width="100%", height="100%", controls=True) 264 | 265 | ``` 266 | 267 | ## Any question? 268 | 269 | Feel free to ask any question regarding Streamlit Elements or this challenge there: [Streamlit Elements Topic](https://discuss.streamlit.io/t/streamlit-elements-build-draggable-and-resizable-dashboards-with-material-ui-nivo-charts-and-more/24616) 270 | -------------------------------------------------------------------------------- /content/Day28.md: -------------------------------------------------------------------------------- 1 | # streamlit-shap 2 | 3 | [`streamlit-shap`](https://github.com/snehankekre/streamlit-shap) is a Streamlit component that provides a wrapper to display [SHAP](https://github.com/slundberg/shap) plots in [Streamlit](https://streamlit.io/). 4 | 5 | The library is developed by our in-house staff [Snehan Kekre](https://github.com/snehankekre) who also maintains the [Streamlit Documentation](https://docs.streamlit.io/) website. 6 | 7 | Firstly, install Streamlit (of course!) then pip install the `streamlit-shap` library: 8 | ```bash 9 | pip install streamlit 10 | pip install streamlit-shap 11 | ``` 12 | 13 | There are also other prerequisite libraries to install (e.g. `matplotlib`, `pandas`, `scikit-learn` and `xgboost`) if you haven't yet done so. 14 | 15 | 16 | ## Demo app 17 | 18 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/streamlit-shap/) 19 | 20 | ## Code 21 | Here's how to use `streamlit-shap`: 22 | ```python 23 | import streamlit as st 24 | from streamlit_shap import st_shap 25 | import shap 26 | from sklearn.model_selection import train_test_split 27 | import xgboost 28 | import numpy as np 29 | import pandas as pd 30 | 31 | st.set_page_config(layout="wide") 32 | 33 | @st.experimental_memo 34 | def load_data(): 35 | return shap.datasets.adult() 36 | 37 | @st.experimental_memo 38 | def load_model(X, y): 39 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=7) 40 | d_train = xgboost.DMatrix(X_train, label=y_train) 41 | d_test = xgboost.DMatrix(X_test, label=y_test) 42 | params = { 43 | "eta": 0.01, 44 | "objective": "binary:logistic", 45 | "subsample": 0.5, 46 | "base_score": np.mean(y_train), 47 | "eval_metric": "logloss", 48 | "n_jobs": -1, 49 | } 50 | model = xgboost.train(params, d_train, 10, evals = [(d_test, "test")], verbose_eval=100, early_stopping_rounds=20) 51 | return model 52 | 53 | st.title("`streamlit-shap` for displaying SHAP plots in a Streamlit app") 54 | 55 | with st.expander('About the app'): 56 | st.markdown('''[`streamlit-shap`](https://github.com/snehankekre/streamlit-shap) is a Streamlit component that provides a wrapper to display [SHAP](https://github.com/slundberg/shap) plots in [Streamlit](https://streamlit.io/). 57 | The library is developed by our in-house staff [Snehan Kekre](https://github.com/snehankekre) who also maintains the [Streamlit Documentation](https://docs.streamlit.io/) website. 58 | ''') 59 | 60 | st.header('Input data') 61 | X,y = load_data() 62 | X_display,y_display = shap.datasets.adult(display=True) 63 | 64 | with st.expander('About the data'): 65 | st.write('Adult census data is used as the example dataset.') 66 | with st.expander('X'): 67 | st.dataframe(X) 68 | with st.expander('y'): 69 | st.dataframe(y) 70 | 71 | st.header('SHAP output') 72 | 73 | # train XGBoost model 74 | model = load_model(X, y) 75 | 76 | # compute SHAP values 77 | explainer = shap.Explainer(model, X) 78 | shap_values = explainer(X) 79 | 80 | with st.expander('Waterfall plot'): 81 | st_shap(shap.plots.waterfall(shap_values[0]), height=300) 82 | with st.expander('Beeswarm plot'): 83 | st_shap(shap.plots.beeswarm(shap_values), height=300) 84 | 85 | explainer = shap.TreeExplainer(model) 86 | shap_values = explainer.shap_values(X) 87 | 88 | with st.expander('Force plot'): 89 | st.subheader('First data instance') 90 | st_shap(shap.force_plot(explainer.expected_value, shap_values[0,:], X_display.iloc[0,:]), height=200, width=1000) 91 | st.subheader('First thousand data instance') 92 | st_shap(shap.force_plot(explainer.expected_value, shap_values[:1000,:], X_display.iloc[:1000,:]), height=400, width=1000) 93 | ``` 94 | 95 | ## Line-by-line explanation 96 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 97 | ```python 98 | import streamlit as st 99 | from streamlit_shap import st_shap 100 | import shap 101 | from sklearn.model_selection import train_test_split 102 | import xgboost 103 | import numpy as np 104 | import pandas as pd 105 | ``` 106 | 107 | Next, we'll set the page layout to be wide such that contents in the Streamlit app can spread the full page width. 108 | ```python 109 | st.set_page_config(layout="wide") 110 | ``` 111 | 112 | Then, we'll load in a dataset from the `shap` library: 113 | ```python 114 | @st.experimental_memo 115 | def load_data(): 116 | return shap.datasets.adult() 117 | ``` 118 | 119 | Subsequently, we'll definite a function called `load_model` for taking in the `X, y` matrix pair as input, perform data splitting to train/test sets, constructing a `DMatrix` and build an XGBoost model. 120 | ```python 121 | @st.experimental_memo 122 | def load_model(X, y): 123 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=7) 124 | d_train = xgboost.DMatrix(X_train, label=y_train) 125 | d_test = xgboost.DMatrix(X_test, label=y_test) 126 | params = { 127 | "eta": 0.01, 128 | "objective": "binary:logistic", 129 | "subsample": 0.5, 130 | "base_score": np.mean(y_train), 131 | "eval_metric": "logloss", 132 | "n_jobs": -1, 133 | } 134 | model = xgboost.train(params, d_train, 10, evals = [(d_test, "test")], verbose_eval=100, early_stopping_rounds=20) 135 | return model 136 | ``` 137 | 138 | The title of the Streamlit app is then displayed: 139 | ```python 140 | st.title("`streamlit-shap` for displaying SHAP plots in a Streamlit app") 141 | ``` 142 | 143 | An about expander box is implemented to provide details of the app: 144 | ```python 145 | with st.expander('About the app'): 146 | st.markdown('''[`streamlit-shap`](https://github.com/snehankekre/streamlit-shap) is a Streamlit component that provides a wrapper to display [SHAP](https://github.com/slundberg/shap) plots in [Streamlit](https://streamlit.io/). 147 | The library is developed by our in-house staff [Snehan Kekre](https://github.com/snehankekre) who also maintains the [Streamlit Documentation](https://docs.streamlit.io/) website. 148 | ''') 149 | ``` 150 | 151 | Here, we'll display the header text along with expander box of the `X` and `y` variables of the Input data: 152 | ```python 153 | st.header('Input data') 154 | X,y = load_data() 155 | X_display,y_display = shap.datasets.adult(display=True) 156 | 157 | with st.expander('About the data'): 158 | st.write('Adult census data is used as the example dataset.') 159 | with st.expander('X'): 160 | st.dataframe(X) 161 | with st.expander('y'): 162 | st.dataframe(y) 163 | ``` 164 | 165 | Here, we'll display the header text for the forthcoming SHAP output: 166 | ```python 167 | st.header('SHAP output') 168 | ``` 169 | 170 | The XGBoost model is then built by using the `load_model` function that was just implemented above. Finally, 171 | ```python 172 | # train XGBoost model 173 | X,y = load_data() 174 | X_display,y_display = shap.datasets.adult(display=True) 175 | 176 | model = load_model(X, y) 177 | ``` 178 | 179 | Here, we'll compute the SHAP values, which are then used to create the Waterfall and Beeswarm plots. 180 | ```python 181 | # compute SHAP values 182 | explainer = shap.Explainer(model, X) 183 | shap_values = explainer(X) 184 | 185 | with st.expander('Waterfall plot'): 186 | st_shap(shap.plots.waterfall(shap_values[0]), height=300) 187 | with st.expander('Beeswarm plot'): 188 | st_shap(shap.plots.beeswarm(shap_values), height=300) 189 | ``` 190 | 191 | Finally, the Tree SHAP algorithms is used to explain the output of ensemble tree models via the `shap.TreeExplainer` command and visualized via the `shap.force_plot` command: 192 | ```python 193 | explainer = shap.TreeExplainer(model) 194 | shap_values = explainer.shap_values(X) 195 | 196 | with st.expander('Force plot'): 197 | st.subheader('First data instance') 198 | st_shap(shap.force_plot(explainer.expected_value, shap_values[0,:], X_display.iloc[0,:]), height=200, width=1000) 199 | st.subheader('First thousand data instance') 200 | st_shap(shap.force_plot(explainer.expected_value, shap_values[:1000,:], X_display.iloc[:1000,:]), height=400, width=1000) 201 | ``` 202 | 203 | ## Further reading 204 | - [`streamlit-shap`](https://github.com/snehankekre/streamlit-shap) 205 | - [SHAP](https://github.com/slundberg/shap) 206 | -------------------------------------------------------------------------------- /content/Day29.md: -------------------------------------------------------------------------------- 1 | # How to make a zero-shot learning text classifier using Hugging Face and Streamlit 2 | 3 | In today's challenge, [Charly Wargnier](https://twitter.com/DataChaz) will walk us through the process of developing a zero-shot learning text classifier using Hugging Face and Streamlit. 4 | 5 | ## Introduction 6 | 7 | Hey Streamliters! 8 | 9 | Today I'm excited to have the opportunity to contribute to the 30DaysofStreamlit challenge via this hands-on tutorial! 🎈 10 | 11 | ## What are we building? 12 | 13 | We will create a zero-shot learning text classifier using Hugging Face's API inference and Distilbart! 14 | 15 | You will have the mighty power to classify keyphrases on-the-fly, fast, and without pre ML training! 16 | 17 | Create classifying labels, paste your keyphrases, and you're off! 18 | 19 | You can set these labels anything, e.g.: 20 | 21 | - Positive, Negative and Neutral for sentiment analysis 22 | - Angry, Happy, Emotional for emotion analysis 23 | - Navigational, Transactional, Informational for intent classification purposes 24 | - Your product range (bags, shoes, boots etc.) 25 | 26 | You decide! 27 | 28 | Excited? Let's dive in! 29 | 30 | ## Read the full blog 31 | 👉 [Read the full blog](https://www.charlywargnier.com/post/how-to-create-a-zero-shot-learning-text-classifier-using-hugging-face-and-streamlit) 32 | 33 | -------------------------------------------------------------------------------- /content/Day3.md: -------------------------------------------------------------------------------- 1 | # st.button 2 | 3 | `st.button` allows the display of a button widget. 4 | 5 | ## What we're building? 6 | 7 | A simple app that performs conditionally prints out alternative messages depending on whether the button was pressed or not. 8 | 9 | Flow of the app: 10 | 11 | 1. By default, the app prints `Goodbye` 12 | 2. Upon clicking on the button, the app displays the alternative message `Why hello there` 13 | 14 | ## Demo app 15 | 16 | The deployed Streamlit app should look something like the one shown in the below link: 17 | 18 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.button/) 19 | 20 | ## Code 21 | 22 | Here's the code to implement the above mentioned app: 23 | 24 | ```python 25 | import streamlit as st 26 | 27 | st.header('st.button') 28 | 29 | if st.button('Say hello'): 30 | st.write('Why hello there') 31 | else: 32 | st.write('Goodbye') 33 | ``` 34 | 35 | ## Line-by-line explanation 36 | 37 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 38 | 39 | ```python 40 | import streamlit as st 41 | ``` 42 | 43 | This is followed by creating a header text for the app: 44 | 45 | ```python 46 | st.header('st.button') 47 | ``` 48 | 49 | Next, we will use conditional statements `if` and `else` for printing alternative messages. 50 | 51 | ```python 52 | if st.button('Say hello'): 53 | st.write('Why hello there') 54 | else: 55 | st.write('Goodbye') 56 | ``` 57 | 58 | As we can see from the above code box, the `st.button()` command accepts the `label` input argument of `Say hello`, which is the text that the button displays. 59 | 60 | The `st.write` command is used to print text messages of either `Why hello there` or `Goodbye` depending on whether the button was clicked or not, which is implemented via: 61 | 62 | 63 | ```python 64 | st.write('Why hello there') 65 | ``` 66 | 67 | and 68 | 69 | ```python 70 | st.write('Goodbye') 71 | ``` 72 | 73 | It is important to note that the above `st.write` statements are placed under the `if` and `else` conditions in order to perform the above mentioned process of alternative displaying of messages 74 | 75 | ## Next steps 76 | 77 | Now that you have created the Streamlit app locally, it's time to deploy it to [Streamlit Community Cloud](https://streamlit.io/cloud) as will be explained soon in an upcoming challenge. 78 | 79 | Because this is the first week of your challenge, we provide the full code (as shown in the code box above) and solution (the demo app) right inside this webpage. 80 | 81 | Moving forward in the next challenges, it is recommended that you first try implementing the Streamlit app yourself. 82 | 83 | Don't worry if you get stuck, you can always take a peek at the solution. 84 | 85 | ## References 86 | 87 | Read about [`st.button`](https://docs.streamlit.io/library/api-reference/widgets/st.button) in the Streamlit API Documentation. 88 | -------------------------------------------------------------------------------- /content/Day30.md: -------------------------------------------------------------------------------- 1 | # The Art of Creating Streamlit Apps 2 | 3 | Today's Day 30 of the *#30DaysOfStreamlit* challenge. Congratulations on making this far in the challenge. 4 | 5 | In this tutorial, we're going to put our newfound knowledge from this learning challenge to create Streamlit apps to solve real-world problem. 6 | 7 | ## Real-world problem 8 | 9 | As a content creator, having access to thumbnail images from YouTube videos are useful resources for social promotion and content creation. 10 | 11 | Let's figure out how we're going to tackle this problem and build a Streamlit app. 12 | 13 | ## Solution 14 | 15 | Today, we're going to build `yt-img-app`, which is a Streamlit app that can extract thumbnail images from YouTube videos. 16 | 17 | In a nutshell, here's the 3 simple steps that we want the Streamlit app to do: 18 | 19 | 1. Accept a YouTube URL as input from users 20 | 2. Perform text processing of the URL to extract the unique YouTube video ID 21 | 3. Use the YouTube video ID as an input to a custom function that retrieves and displays the thumbnail image from YouTube videos 22 | 23 | ## Instructions 24 | 25 | To get started in using the Streamlit app, copy and paste a YouTube URL into the input text box. 26 | 27 | ## Demo app 28 | 29 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/yt-img-app/) 30 | 31 | ## Code 32 | Here's how to build the `yt-img-app` Streamlit app: 33 | ```python 34 | import streamlit as st 35 | 36 | st.title('🖼️ yt-img-app') 37 | st.header('YouTube Thumbnail Image Extractor App') 38 | 39 | with st.expander('About this app'): 40 | st.write('This app retrieves the thumbnail image from a YouTube video.') 41 | 42 | # Image settings 43 | st.sidebar.header('Settings') 44 | img_dict = {'Max': 'maxresdefault', 'High': 'hqdefault', 'Medium': 'mqdefault', 'Standard': 'sddefault'} 45 | selected_img_quality = st.sidebar.selectbox('Select image quality', ['Max', 'High', 'Medium', 'Standard']) 46 | img_quality = img_dict[selected_img_quality] 47 | 48 | yt_url = st.text_input('Paste YouTube URL', 'https://youtu.be/JwSS70SZdyM') 49 | 50 | def get_ytid(input_url): 51 | if 'youtu.be' in input_url: 52 | ytid = input_url.split('/')[-1] 53 | if 'youtube.com' in input_url: 54 | ytid = input_url.split('=')[-1] 55 | return ytid 56 | 57 | # Display YouTube thumbnail image 58 | if yt_url != '': 59 | ytid = get_ytid(yt_url) # yt or yt_url 60 | 61 | yt_img = f'http://img.youtube.com/vi/{ytid}/{img_quality}.jpg' 62 | st.image(yt_img) 63 | st.write('YouTube video thumbnail image URL: ', yt_img) 64 | else: 65 | st.write('☝️ Enter URL to continue ...') 66 | ``` 67 | 68 | ## Line-by-line explanation 69 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 70 | ```python 71 | import streamlit as st 72 | ``` 73 | 74 | Next, we display the app's title and accompanying header: 75 | ```python 76 | st.title('🖼️ yt-img-app') 77 | st.header('YouTube Thumbnail Image Extractor App') 78 | ``` 79 | While we're at it, we'll might as well throw in an About expandable box. 80 | ```python 81 | with st.expander('About this app'): 82 | st.write('This app retrieves the thumbnail image from a YouTube video.') 83 | 84 | Here, we create selection box for accepting user input on the image quality to use. 85 | ```python 86 | # Image settings 87 | st.sidebar.header('Settings') 88 | img_dict = {'Max': 'maxresdefault', 'High': 'hqdefault', 'Medium': 'mqdefault', 'Standard': 'sddefault'} 89 | selected_img_quality = st.sidebar.selectbox('Select image quality', ['Max', 'High', 'Medium', 'Standard']) 90 | img_quality = img_dict[selected_img_quality] 91 | ``` 92 | 93 | An input text box is displayed to accept user input on the YouTube video URL to use for extracting the image from. 94 | ```python 95 | yt_url = st.text_input('Paste YouTube URL', 'https://youtu.be/JwSS70SZdyM') 96 | ``` 97 | 98 | A custom function for performing text processing of the input URL. 99 | ```python 100 | def get_ytid(input_url): 101 | if 'youtu.be' in input_url: 102 | ytid = input_url.split('/')[-1] 103 | if 'youtube.com' in input_url: 104 | ytid = input_url.split('=')[-1] 105 | return ytid 106 | ``` 107 | 108 | Finally, we use flow control to determine whether to display a reminder to enter the URL (i.e. as in the `else` statement) or to display the YouTube thumbnail image (i.e. as in the `if` statement). 109 | ```python 110 | # Display YouTube thumbnail image 111 | if yt_url != '': 112 | ytid = get_ytid(yt_url) # yt or yt_url 113 | 114 | yt_img = f'http://img.youtube.com/vi/{ytid}/{img_quality}.jpg' 115 | st.image(yt_img) 116 | st.write('YouTube video thumbnail image URL: ', yt_img) 117 | else: 118 | st.write('☝️ Enter URL to continue ...') 119 | ``` 120 | 121 | ## Summary 122 | 123 | In summary, we have seen that in the creation of any Streamlit app, we normally start by first identifying and defining the problem. Next, we devise a solution to tackle the problem by breaking it down into the granular steps, which we implement in the Streamlit app. 124 | 125 | Here, we also have to determine which data or information that we need as input from users, the approach and method to use in processing the user input in order to produce the final desired output. 126 | 127 | Hope you enjoyed this tutorial, Happy Streamlit-ing! 128 | -------------------------------------------------------------------------------- /content/Day4.md: -------------------------------------------------------------------------------- 1 | # Building Streamlit apps with Ken Jee 2 | 3 | ## Watch Ken's video 4 | 5 | Let's follow along and watch how [Ken Jee](https://www.youtube.com/c/KenJee1) builds a Streamlit app in this video: 6 | 7 | [![Data Science Portfolio Project from Scratch](https://img.youtube.com/vi/Yk-unX4KnV4/0.jpg)]()] 8 | -------------------------------------------------------------------------------- /content/Day5.md: -------------------------------------------------------------------------------- 1 | # st.write 2 | 3 | `st.write` allows writing text and arguments to the Streamlit app. 4 | 5 | In addition to being able to display text, the following can also be displayed via the `st.write()` command: 6 | 7 | 8 | - Prints strings; works like `st.markdown()` 9 | - Displays a Python `dict` 10 | - Displays `pandas` DataFrame can be displayed as a table 11 | - Plots/graphs/figures from `matplotlib`, `plotly`, `altair`, `graphviz`, `bokeh` 12 | - And more (see [st.write on API docs](https://docs.streamlit.io/library/api-reference/write-magic/st.write)) 13 | 14 | ## What we're building? 15 | 16 | A simple app showing the various ways on how to use the `st.write()` command for displaying text, numbers, DataFrames and plots. 17 | 18 | ## Demo app 19 | 20 | The deployed Streamlit app should look something like the one shown in the below link: 21 | 22 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.write/) 23 | 24 | ## Code 25 | 26 | Here's how to use st.write: 27 | 28 | ```python 29 | import numpy as np 30 | import altair as alt 31 | import pandas as pd 32 | import streamlit as st 33 | 34 | st.header('st.write') 35 | 36 | # Example 1 37 | 38 | st.write('Hello, *World!* :sunglasses:') 39 | 40 | # Example 2 41 | 42 | st.write(1234) 43 | 44 | # Example 3 45 | 46 | df = pd.DataFrame({ 47 | 'first column': [1, 2, 3, 4], 48 | 'second column': [10, 20, 30, 40] 49 | }) 50 | st.write(df) 51 | 52 | # Example 4 53 | 54 | st.write('Below is a DataFrame:', df, 'Above is a dataframe.') 55 | 56 | # Example 5 57 | 58 | df2 = pd.DataFrame( 59 | np.random.randn(200, 3), 60 | columns=['a', 'b', 'c']) 61 | c = alt.Chart(df2).mark_circle().encode( 62 | x='a', y='b', size='c', color='c', tooltip=['a', 'b', 'c']) 63 | st.write(c) 64 | ``` 65 | 66 | ## Line-by-line explanation 67 | 68 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 69 | 70 | ```python 71 | import streamlit as st 72 | ``` 73 | 74 | This is followed by creating a header text for the app: 75 | 76 | ```python 77 | st.header('st.write') 78 | ``` 79 | 80 | **Example 1** 81 | Its basic use case is to display text and Markdown-formatted text: 82 | 83 | ```python 84 | st.write('Hello, *World!* :sunglasses:') 85 | ``` 86 | 87 | **Example 2** 88 | As mentioned above, it can also be used to display other data formats such as numbers: 89 | 90 | ```python 91 | st.write(1234) 92 | ``` 93 | 94 | **Example 3** 95 | DataFrames can also be displayed as follows: 96 | 97 | ```python 98 | df = pd.DataFrame({ 99 | 'first column': [1, 2, 3, 4], 100 | 'second column': [10, 20, 30, 40] 101 | }) 102 | st.write(df) 103 | ``` 104 | 105 | **Example 4** 106 | You can pass in multiple arguments: 107 | 108 | ```python 109 | st.write('Below is a DataFrame:', df, 'Above is a dataframe.') 110 | ``` 111 | 112 | **Example 5** 113 | Finally, you can also display plots as well by passing it to a variable as follows: 114 | 115 | ```python 116 | df2 = pd.DataFrame( 117 | np.random.randn(200, 3), 118 | columns=['a', 'b', 'c']) 119 | c = alt.Chart(df2).mark_circle().encode( 120 | x='a', y='b', size='c', color='c', tooltip=['a', 'b', 'c']) 121 | st.write(c) 122 | ``` 123 | 124 | ## Demo app 125 | 126 | The deployed Streamlit app should look something like the one shown in the below link: 127 | 128 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.write/) 129 | 130 | ## Next steps 131 | 132 | Now that you have created the Streamlit app locally, it's time to deploy it to [Streamlit Community Cloud](https://streamlit.io/cloud) as will be explained soon in an upcoming challenge. 133 | 134 | Because this is the first week of your challenge, we provide the full code (as shown in the code box above) and solution (the demo app) right inside this webpage. 135 | 136 | Moving forward in the next challenges, it is recommended that you first try implementing the Streamlit app yourself. 137 | 138 | Don't worry if you get stuck, you can always take a peek at the solution. 139 | 140 | ## Further reading 141 | 142 | In addition to [`st.write`](https://docs.streamlit.io/library/api-reference/write-magic/st.write), you can explore the other ways of displaying text: 143 | 144 | - [`st.markdown`](https://docs.streamlit.io/library/api-reference/text/st.markdown) 145 | - [`st.header`](https://docs.streamlit.io/library/api-reference/text/st.header) 146 | - [`st.subheader`](https://docs.streamlit.io/library/api-reference/text/st.subheader) 147 | - [`st.caption`](https://docs.streamlit.io/library/api-reference/text/st.caption) 148 | - [`st.text`](https://docs.streamlit.io/library/api-reference/text/st.text) 149 | - [`st.latex`](https://docs.streamlit.io/library/api-reference/text/st.latex) 150 | - [`st.code`](https://docs.streamlit.io/library/api-reference/text/st.code) 151 | -------------------------------------------------------------------------------- /content/Day6.md: -------------------------------------------------------------------------------- 1 | # Uploading your Streamlit app to GitHub 2 | 3 | ## GitHub 4 | 5 | Git is a software for keeping track of all changes made to code (i.e. version control). GitHub is a Git repository hosting service that makes data and code publicly available on the web, which allows team collaboration and allow others to contribute to the repo. 6 | 7 | Housing your Streamlit app in a GitHub repository will allow apps to be deployed to the cloud (the next challenge). 8 | 9 | ## Sign up for GitHub 10 | 11 | Firstly, sign up for a [GitHub](https://github.com/) account. 12 | 13 | ## Create a GitHub repository 14 | 15 | Follow the following steps to create a GitHub repository: 16 | - In the top right hand corner, click on the **"+"** icon which should reveal a drop-down menu, then click on **"New repository"** (*Figure 1*). 17 | 18 | - This should bring to a new webpage called **"Create a new repository"**. Under the **"Repository name"** field, enter a name for your repository, for example, `helloworld` (***Figure 2***). 19 | 20 | - Under the **"Initialize this repository with:"** field, tick on **"Add a README file"**. 21 | 22 | - Finally, click on **"Create repository"** (Figure 3). 23 | 24 | Your newly created repository will be available at `https://github.com/dataprofessor/helloworld` where `dataprofessor` is the username and `helloworld` is the repository name. 25 | 26 | Below is the screenshot of the newly created repo (Figure 4): 27 | 28 | ## Upload files to the GitHub repo 29 | 30 | Slightly above the file table and adjacent to the green **Code** button, click on **Add file** > **Upload files** (Figure 5). 31 | 32 | This will bring you to a new webpage where the central box says ***Drag files here to add them to your repository*** and **choose your files**, which you can either drag-and-drop files into this box or click on the **choose your files** link to choose files from your local computer. 33 | 34 | Click on **Commit changes** to proceed further (Figure 6). 35 | -------------------------------------------------------------------------------- /content/Day7.md: -------------------------------------------------------------------------------- 1 | # Deploying your Streamlit app with Streamlit Community Cloud 2 | 3 | ## Streamlit Community Cloud 4 | 5 | [Streamlit Community Cloud](https://streamlit.io/cloud) is a hosting service for easily deploying Streamlit apps. 6 | 7 | ## Sign up for Streamlit Community Cloud 8 | 9 | You can easily sign up for [Streamlit Community Cloud](https://streamlit.io/cloud) by simply logging in with Google or GitHub account. 10 | 11 | ## Deploy a Streamlit app 12 | 13 | To deploy a Streamlit app, do the following: 14 | 1. Sign in with GitHub or Gmail credentials 15 | 2. Pick a repo, branch and file 16 | 3. Click Deploy 17 | 18 | Then any time you do a git push your app will update immediately. 19 | -------------------------------------------------------------------------------- /content/Day8.md: -------------------------------------------------------------------------------- 1 | # st.slider 2 | 3 | `st.slider` allows the display of a slider input widget. 4 | 5 | The following data types are supported: int, float, date, time, and datetime. 6 | 7 | ## What we're building? 8 | 9 | A simple app that shows the various ways on how to accept user input by adjusting the slider widget. 10 | 11 | Flow of the app: 12 | 1. User selects value by adjusting the slider widget 13 | 2. App prints out the selected value 14 | 15 | ## Demo app 16 | 17 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.slider/) 18 | 19 | 20 | ## Code 21 | Here's how to use st.slider: 22 | 23 | ```python 24 | import streamlit as st 25 | from datetime import time, datetime 26 | 27 | st.header('st.slider') 28 | 29 | # Example 1 30 | 31 | st.subheader('Slider') 32 | 33 | age = st.slider('How old are you?', 0, 130, 25) 34 | st.write("I'm ", age, 'years old') 35 | 36 | # Example 2 37 | 38 | st.subheader('Range slider') 39 | 40 | values = st.slider( 41 | 'Select a range of values', 42 | 0.0, 100.0, (25.0, 75.0)) 43 | st.write('Values:', values) 44 | 45 | # Example 3 46 | 47 | st.subheader('Range time slider') 48 | 49 | appointment = st.slider( 50 | "Schedule your appointment:", 51 | value=(time(11, 30), time(12, 45))) 52 | st.write("You're scheduled for:", appointment) 53 | 54 | # Example 4 55 | 56 | st.subheader('Datetime slider') 57 | 58 | start_time = st.slider( 59 | "When do you start?", 60 | value=datetime(2020, 1, 1, 9, 30), 61 | format="MM/DD/YY - hh:mm") 62 | st.write("Start time:", start_time) 63 | 64 | ``` 65 | 66 | ## Line-by-line explanation 67 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` like so: 68 | ```python 69 | import streamlit as st 70 | from datetime import time, datetime 71 | ``` 72 | 73 | This is followed by creating a header text for the app: 74 | ```python 75 | st.header('st.slider') 76 | ``` 77 | 78 | **Example 1** 79 | 80 | Slider: 81 | 82 | ```python 83 | st.subheader('Slider') 84 | 85 | age = st.slider('How old are you?', 0, 130, 25) 86 | st.write("I'm ", age, 'years old') 87 | ``` 88 | 89 | As we can see, the `st.slider()` command 90 | is used to collect user input about the age of users. 91 | 92 | The first input argument displays the text just above the **slider** widget asking `'How old are you?'`. 93 | 94 | The following three integers `0, 130, 25` represents the minimum, maximum and default values, respectively. 95 | 96 | **Example 2** 97 | 98 | Range slider: 99 | 100 | ```python 101 | st.subheader('Range slider') 102 | 103 | values = st.slider( 104 | 'Select a range of values', 105 | 0.0, 100.0, (25.0, 75.0)) 106 | st.write('Values:', values) 107 | ``` 108 | 109 | The range slider allow selection of a lower and upper bound value pair. 110 | 111 | The first input argument displays the text just above the **range slider** widget asking `'Select a range of values'`. 112 | 113 | The following three arguments `0.0, 100.0, (25.0, 75.0)` represents the minimum and maximum values while the last tuple denotes the default values to use as the selected lower (25.0) and upper (75.0) bound values. 114 | 115 | **Example 3** 116 | 117 | Range time slider: 118 | 119 | ```python 120 | st.subheader('Range time slider') 121 | 122 | appointment = st.slider( 123 | "Schedule your appointment:", 124 | value=(time(11, 30), time(12, 45))) 125 | st.write("You're scheduled for:", appointment) 126 | ``` 127 | 128 | The range time slider allows selection of a lower and upper bound value pair of datetime. 129 | 130 | The first input argument displays the text just above the **range time slider** widget asking `'Schedule your appointment:`. 131 | 132 | The default values for the lower and upper bound value pairs of datetime are set to 11:30 and 12:45, respectively. 133 | 134 | **Example 4** 135 | 136 | Datetime slider: 137 | 138 | ```python 139 | st.subheader('Datetime slider') 140 | 141 | start_time = st.slider( 142 | "When do you start?", 143 | value=datetime(2020, 1, 1, 9, 30), 144 | format="MM/DD/YY - hh:mm") 145 | st.write("Start time:", start_time) 146 | ``` 147 | 148 | The datetime slider allows selection of a datetime. 149 | 150 | The first input argument displays the text just above the **datetime** slider widget asking `'When do you start?'`. 151 | 152 | The default value for the datetime was set using the `value` option to be January 1, 2020 at 9:30 153 | 154 | ## Further reading 155 | You can also explore the following related widget: 156 | - [`st.select_slider`](https://docs.streamlit.io/library/api-reference/widgets/st.select_slider) 157 | -------------------------------------------------------------------------------- /content/Day9.md: -------------------------------------------------------------------------------- 1 | # st.line_chart 2 | 3 | `st.line_chart` displays a line chart. 4 | 5 | This is syntax-sugar around `st.altair_chart`. The main difference is this command uses the data's own column and indices to figure out the chart's spec. As a result this is easier to use for many "just plot this" scenarios, while being less customizable. 6 | 7 | If `st.line_chart` does not guess the data specification correctly, try specifying your desired chart using st.altair_chart. 8 | 9 | ## What we're building? 10 | 11 | A simple app for displaying a line chart. 12 | 13 | Flow of the app: 14 | 1. Create a `Pandas` DataFrame from numbers randomly generated via `NumPy`. 15 | 2. Create and display the line chart via `st.line_chart()` command. 16 | 17 | ## Demo app 18 | 19 | [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/dataprofessor/st.line_chart/) 20 | 21 | ## Code 22 | Here's how to use [`st.line_chart`](https://docs.streamlit.io/library/api-reference/charts/st.line_chart): 23 | ```python 24 | import streamlit as st 25 | import pandas as pd 26 | import numpy as np 27 | 28 | st.header('Line chart') 29 | 30 | chart_data = pd.DataFrame( 31 | np.random.randn(20, 3), 32 | columns=['a', 'b', 'c']) 33 | 34 | st.line_chart(chart_data) 35 | 36 | ``` 37 | 38 | ## Line-by-line explanation 39 | The very first thing to do when creating a Streamlit app is to start by importing the `streamlit` library as `st` as well as other libraries like so: 40 | ```python 41 | import streamlit as st 42 | import pandas as pd 43 | import numpy as np 44 | ``` 45 | 46 | Next, we create a header text for the app: 47 | ```python 48 | st.header('Line chart') 49 | ``` 50 | 51 | Then, we create a DataFrame of randomly generated numbers that contains 3 columns. 52 | ```python 53 | chart_data = pd.DataFrame( 54 | np.random.randn(20, 3), 55 | columns=['a', 'b', 'c']) 56 | ``` 57 | 58 | Finally, a line chart is created by using `st.line_chart()` with the DataFrame stored in the `chart_data` variable as the input data: 59 | ```python 60 | st.line_chart(chart_data) 61 | ``` 62 | 63 | ## Further reading 64 | Read more about the following related Streamlit command from which [`st.line_chart`](https://docs.streamlit.io/library/api-reference/charts/st.line_chart) is based on: 65 | - [`st.altair_chart`](https://docs.streamlit.io/library/api-reference/charts/st.altair_chart) 66 | -------------------------------------------------------------------------------- /content/figures/Day1.csv: -------------------------------------------------------------------------------- 1 | img,figure,caption 2 | 2C9104F7-CF84-4DAF-9004-52BB4644CF28.png, Figure 1, Streamlit demo app is launched via "streamlit hello" 3 | -------------------------------------------------------------------------------- /content/figures/Day20.csv: -------------------------------------------------------------------------------- 1 | img,figure,caption 2 | 77EC58A5-25FD-4477-A74E-421333312514.jpeg, Figure 1, Join the Tech Twitter Space on What is Streamlit? (Hosted by Francesco Ciulla) available at https://twitter.com/i/spaces/1dRJZlbglXMKB 3 | -------------------------------------------------------------------------------- /content/figures/Day6.csv: -------------------------------------------------------------------------------- 1 | img,figure,caption 2 | 8ED4483A-58C6-4F76-BE59-C8CC6DCDB95E.jpeg, Figure 1, Creating a new repository 3 | 0CEEBB8C-29FB-4B85-9932-CEF642777A8A.jpeg, Figure 2, Enter the repository name "helloworld" 4 | 7A7B0072-71ED-42BD-B985-B0D35CF03A1F.jpeg, Figure 3, Setting the initial settings (Adding a README file) and confirming the creation of the new repository 5 | F8DCC7EB-D497-426D-904F-6941E2C4B750.jpeg, Figure 4, New repository called "helloworld" is now created along with its first file (README.md) 6 | 8032B4CC-A9BD-4B4F-8DFB-EBE7326886DE.jpeg, Figure 5, Initiate the uploading of file(s) to the GitHub repo 7 | 8085E82C-304F-48EE-8AD6-3F941E31860B.jpeg, Figure 6, Drag and drop files to be uploaded into the specified central box. Or alternatively click on "choose your files" that will bring up a file selection window where files can be selected for upload 8 | -------------------------------------------------------------------------------- /content/images/0CEEBB8C-29FB-4B85-9932-CEF642777A8A.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/content/images/0CEEBB8C-29FB-4B85-9932-CEF642777A8A.jpeg -------------------------------------------------------------------------------- /content/images/2C9104F7-CF84-4DAF-9004-52BB4644CF28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/content/images/2C9104F7-CF84-4DAF-9004-52BB4644CF28.png -------------------------------------------------------------------------------- /content/images/77EC58A5-25FD-4477-A74E-421333312514.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/content/images/77EC58A5-25FD-4477-A74E-421333312514.jpeg -------------------------------------------------------------------------------- /content/images/7A7B0072-71ED-42BD-B985-B0D35CF03A1F.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/content/images/7A7B0072-71ED-42BD-B985-B0D35CF03A1F.jpeg -------------------------------------------------------------------------------- /content/images/8032B4CC-A9BD-4B4F-8DFB-EBE7326886DE.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/content/images/8032B4CC-A9BD-4B4F-8DFB-EBE7326886DE.jpeg -------------------------------------------------------------------------------- /content/images/8085E82C-304F-48EE-8AD6-3F941E31860B.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/content/images/8085E82C-304F-48EE-8AD6-3F941E31860B.jpeg -------------------------------------------------------------------------------- /content/images/8ED4483A-58C6-4F76-BE59-C8CC6DCDB95E.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/content/images/8ED4483A-58C6-4F76-BE59-C8CC6DCDB95E.jpeg -------------------------------------------------------------------------------- /content/images/F8DCC7EB-D497-426D-904F-6941E2C4B750.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/content/images/F8DCC7EB-D497-426D-904F-6941E2C4B750.jpeg -------------------------------------------------------------------------------- /content/images/readme.md: -------------------------------------------------------------------------------- 1 | # images 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas 2 | click==8.0 3 | -------------------------------------------------------------------------------- /streamlit-logo-secondary-colormark-darktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/streamlit/30days/2444b0425d6a0b446c788fdb0e0c776550614455/streamlit-logo-secondary-colormark-darktext.png -------------------------------------------------------------------------------- /streamlit_app.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import urllib.request 4 | 5 | import numpy as np 6 | import pandas as pd 7 | import streamlit as st 8 | from PIL import Image 9 | 10 | 11 | def update_params(): 12 | st.experimental_set_query_params(challenge=st.session_state.day) 13 | 14 | 15 | md_files = sorted( 16 | [int(x.strip("Day").strip(".md")) for x in glob.glob1("content", "*.md")] 17 | ) 18 | 19 | # Logo and Navigation 20 | col1, col2, col3 = st.columns((1, 4, 1)) 21 | with col2: 22 | st.image(Image.open("streamlit-logo-secondary-colormark-darktext.png")) 23 | st.markdown("# 30 Days of Streamlit") 24 | 25 | days_list = [f"Day {x}" for x in md_files] 26 | 27 | query_params = st.experimental_get_query_params() 28 | 29 | try: 30 | if query_params and query_params["challenge"][0] in days_list: 31 | st.session_state.day = query_params["challenge"][0] 32 | except KeyError: 33 | st.session_state.day = days_list[0] 34 | 35 | selected_day = st.selectbox( 36 | "Start the Challenge 👇", days_list, key="day", on_change=update_params 37 | ) 38 | 39 | with st.expander("About the #30DaysOfStreamlit"): 40 | st.markdown( 41 | """ 42 | The **#30DaysOfStreamlit** is a coding challenge designed to help you get started in building Streamlit apps. 43 | 44 | Particularly, you'll be able to: 45 | - Set up a coding environment for building Streamlit apps 46 | - Build your first Streamlit app 47 | - Learn about all the awesome input/output widgets to use for your Streamlit app 48 | """ 49 | ) 50 | 51 | # Sidebar 52 | st.sidebar.header("About") 53 | st.sidebar.markdown( 54 | "[Streamlit](https://streamlit.io) is a Python library that allows the creation of interactive, data-driven web applications in Python." 55 | ) 56 | 57 | st.sidebar.header("Resources") 58 | st.sidebar.markdown( 59 | """ 60 | - [Streamlit Documentation](https://docs.streamlit.io/) 61 | - [Cheat sheet](https://docs.streamlit.io/library/cheatsheet) 62 | - [Book](https://www.amazon.com/dp/180056550X) (Getting Started with Streamlit for Data Science) 63 | - [Blog](https://blog.streamlit.io/how-to-master-streamlit-for-data-science/) (How to master Streamlit for data science) 64 | """ 65 | ) 66 | 67 | st.sidebar.header("Deploy") 68 | st.sidebar.markdown( 69 | "You can quickly deploy Streamlit apps using [Streamlit Community Cloud](https://streamlit.io/cloud) in just a few clicks." 70 | ) 71 | 72 | # Display content 73 | for i in days_list: 74 | if selected_day == i: 75 | st.markdown(f"# 🗓️ {i}") 76 | j = i.replace(" ", "") 77 | with open(f"content/{j}.md", "r") as f: 78 | st.markdown(f.read()) 79 | if os.path.isfile(f"content/figures/{j}.csv") == True: 80 | st.markdown("---") 81 | st.markdown("### Figures") 82 | df = pd.read_csv(f"content/figures/{j}.csv", engine="python") 83 | for i in range(len(df)): 84 | st.image(f"content/images/{df.img[i]}") 85 | st.info(f"{df.figure[i]}: {df.caption[i]}") 86 | --------------------------------------------------------------------------------